.NET Framework 4.6 集成 GStreamer 时的 DLL 名称映射问题咨询
问题1:为什么安装的GStreamer DLL都带lib前缀
GStreamer的Windows官方安装包分为MinGW编译版和MSVC编译版两类,你安装的是MinGW构建的版本,这类版本输出的DLL默认会携带类Unix平台习惯的lib前缀,和Windows系统版本没有关联。公开代码示例大多使用MSVC编译的版本,输出的DLL本身不带lib前缀,所以和你遇到的情况不一致。
问题2:除重写NuGet包外的适配方案
- 方案1:卸载现有GStreamer,重新下载安装MSVC编译的官方版本,安装后输出的DLL本身无
lib前缀,直接匹配NuGet包的查找逻辑,是改造成本最低的方案。 - 方案2:无需重装,把GStreamer安装目录bin路径下所有带
lib前缀的相关DLL复制一份到应用运行目录,将副本文件名中的lib前缀删除即可,不需要修改原安装文件。 - 方案3:制作转发DLL,新建一个名为
gstreamer-1.0-0.dll的空动态库,通过模块转发规则把所有函数调用指向libgstreamer-1.0-0.dll的对应实现,不需要修改业务代码也不需要改动原GStreamer文件。
问题3:.NET Framework 4.6下拦截DllImport查找逻辑的方法
可以实现,有两个成熟可行的方案:
- 方案1:预加载+API挂钩。在程序入口点(例如
Main方法最开头,所有GStreamer相关调用执行前),先通过Win32 API加载带lib前缀的目标DLL,再用轻量挂钩工具拦截LoadLibraryExW系统调用,当检测到请求加载的DLL名称为gstreamer-1.0-0.dll时,直接返回已经加载好的libgstreamer-1.0-0.dll的模块句柄即可。
预加载代码示例:
// 声明Win32 API [DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Auto)] public static extern IntPtr LoadLibrary(string lpFileName); // 程序启动时优先调用 LoadLibrary("libgstreamer-1.0-0.dll"); // 其余依赖的带lib前缀的GStreamer相关DLL也可按该方式提前加载
- 方案2:配置映射。如果运行环境支持,可在
app.config的runtime节点下添加<dllmap dll="gstreamer-1.0-0.dll" target="libgstreamer-1.0-0.dll"/>配置完成自动名称映射,不需要修改代码。如果配置不生效,优先使用第一种挂钩预加载方案。
内容的提问来源于stack exchange,提问作者Chris Lees
相关产品推荐
相关产品推荐

