我正在为LibVLC媒体库编写一个超级简单的超轻量级.Net包装器,因为我需要访问的唯一内容是播放,暂停和停止媒体文件。我已经发布了几个问题并得到了一些答案但不幸的是我只是留下了更多问题。
我们将从顶部开始工作。
文档首先说明我必须通过调用具有此规范的函数来初始化VLC:
libvlc_instance_t* libvlc_new (int argc, const char *const *argv)
我为其定义了以下方法:
[DllImport("libvlc", EntryPoint = "libvlc_new",
CallingConvention = CallingConvention.Cdecl)]
public static extern IntPtr NewCore(int argc, IntPtr argv);
我正在调用这样的函数:
private IntPtr Instance;
this.Instance = DGLibVLC.NewCore(0, IntPtr.Zero);
我尝试了几种不同的方法。最初我不知道CallingConvention导致了一个不平衡的堆栈,它首先把我带到了这里。这个问题已经解决了,并且该方法经历了几次迭代,其中没有一次证明是成功的,我的意思是在方法调用之后IntPtr始终为0。我已经尝试过它,就像它在上面一样,第二个参数是String[] argc
,[MarshalAs(UnmanagedType.LPArray, ArraySubType = UnmanagedType.LPStr)] string[]
,
我试过让它返回Long(这实际上导致Long有一个值),但到目前为止没有任何工作正常。
有没有人知道从LibVLC DLL库调用此函数的正确方法?
编辑:根据建议,我尝试调用库的错误消息功能:
规格:
const char* libvlc_errmsg (void)
实现:
[DllImport("libvlc", EntryPoint = "libvlc_errmsg",
CallingConvention = CallingConvention.Cdcel)]
public static extern string GetLastError();
呼叫:
Console.WriteLine(DGLibVLC.GetLastError());
结果:
Null
文档说明如果没有错误它将返回Null。这必须表明初始函数调用NewCore
工作正常,但某些方面仍然存在问题。
要覆盖所有基础,我检查了DLL与文档匹配,他们这样做。 2.0.6.0。我引用的文档是here。
编辑:我可以确认没有错误。当使用初始化为零长变量来存储NewCore的结果时,我可以看到它返回一些东西。我在这里做的错误是我试图存储由非托管函数返回的指针,该函数返回指向对象的指针。如何将指针存储到传回的不透明结构引用?
答案 0 :(得分:1)
它与你调用函数的方式没有任何关系。当你从libvlc_new()获得IntPtr.Zero时,你无法到达任何地方。这意味着"出现了错误"。您首先需要关注错误报告,调用libvlc_errmsg()来尝试获取问题的描述。
答案 1 :(得分:1)
因此,经过多次环顾四周并提出问题,我已经完整了一圈。 我深入研究了LibVLC.Net,发现他们是如何导入DLL函数并调整他们对我自己的包装器所做的,并且它有效。
总结:
在开头的代码中声明了一些Win32 API函数:
[DllImport("kernel32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
private static extern bool SetDllDirectory(string lpPathName);
[DllImport("kernel32", SetLastError = true)]
private static extern IntPtr LoadLibrary(string lpFileName);
[DllImport("kernel32", CharSet = CharSet.Ansi, ExactSpelling = true, SetLastError = true)]
private static extern IntPtr GetProcAddress(IntPtr hModule, string procName);
[DllImport("kernel32.dll", SetLastError = true)]
private static extern bool FreeLibrary(IntPtr hModule);
处理为dll提供句柄并设置目录搜索路径。
我不知道究竟是什么意思,但是当你初始化LibVLC.Net库(主要对象)时,它几乎可以加载每个函数:
m_libvlc_media_player_new = (libvlc_media_player_new_signature)LoadDelegate<libvlc_media_player_new_signature>("libvlc_media_player_new");
这个委托的定义如下:
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
private delegate IntPtr libvlc_media_player_new_signature(IntPtr p_instance);
//==========================================================================
private readonly libvlc_media_player_new_signature m_libvlc_media_player_new;
//==========================================================================
public IntPtr libvlc_media_player_new(IntPtr p_instance)
{
VerifyAccess();
return m_libvlc_media_player_new(p_instance);
}
它有一个公共函数,一旦定义就会调用委托。
我简单地删除了定义库实例的函数,并仅导入了我需要的功能。
非常感谢所有耐心帮助我的人。没有你的帮助,我可能无法找到解决方案。
编辑:好的,不是那样的。这是LibVLC插件目录的位置。所以这是愚蠢的事情 - .-;