正确调用非托管DLL函数的约定

时间:2013-08-13 11:38:03

标签: c# .net-4.0 pinvoke libvlc

我正在尝试为LibVLC DLL库编写一个简单的超简单轻量级包装器。我不需要访问太多,只需要播放暂停和停止媒体文件的能力。我正在查看文档和我发现的其他链接,它解释了旧版本的LibVLC,但它已经过时了最新版本。我也尝试了LibVLC.Net,但它也已经过时了,我找不到我在源代码中寻找的内容,以便将它与我想要导出的函数相匹配。

我正在尝试导出以下签名:

libvlc_new (int argc, const char *const *argv)

描述:

argc    the number of arguments (should be 0)
argv    list of arguments (should be NULL)

这就是我正在尝试的方法。

[DllImport("libvlc", EntryPoint = "libvlc_new")]
public static extern IntPtr New(Int32 argc, String[] argv);

描述表明它应该是一个数组,我认为问题是第二个参数。我试过了:

[MarshalAs(UnmanagedType.LPArray, ArraySubType = UnmanagedType.LPStr)] String[] argv

根据here,还有一些其他选项,如String和StringBuilder,如建议的here但仍然会发生每次调用函数时我得到一个不平衡的PInvoke堆栈

我需要知道这个函数的正确调用约定,以及其他几个函数。 “PInvoke For Dummies”在线参考将非常好。

1 个答案:

答案 0 :(得分:2)

如果只允许NULL,则声明参数类型没有太大意义。只需将其声明为IntPtr并传递IntPtr.Zero。

调试器指出你忘了宣布CallingConvention。它不是.NET的默认设置,这是一个__cdecl函数。所以适当的声明是:

[DllImport("libvlc", EntryPoint = "libvlc_new", 
     CallingConvention = CallingConvention.Cdecl)]
public static extern IntPtr New(int argc, IntPtr argv);

被称为:

New(0, IntPtr.Zero);

试着选择一个更好的名字......