具有相同名称的非托管C++ DLL在同一进程中共存

Irv*_*Irv 6 c++ dll visual-studio

使用Visual Studio c ++ V10,我试图找出如何构建DLL并解决DLL命名冲突.这是详细信息.

S公司出售一种名为的产品M.EXE.假设M.EXE安装在\S\BIN\M.EXE.公司S静态链接到一个名为的DLL U.DLL,它安装在 \S\BIN\U.DLL. U.DLL包含开源代码,并使用Visual C++编译器选项构建/Zc:wchar_t-,该选项不将wchar识别为本机类型.

公司C发布了一个名为的DLL O.DLL,并发布了此DLL的API,并为其提供了一个导入库O.DLL.假设O.DLL安装在\C\BIN\O.DLL. O.DLL静态链接到一个名为的DLL U.DLL,它安装在\C\BIN\U.DLL. U.DLL是基于相同的开源代码构建的,但是使用Visual C++编译器选项构建/Zc:wchar_t,它们可以识别wchar_t为本机类型.

理想情况下,公司C和公司S将同意U.DLL使用相同的Visual C++选项进行构建,但这是不可能的.

M.EXE从公司S是可扩展的,因为我可以在非托管C++中构建我自己的DLL,如果我正确设置了所有内容NODE.DLL,M.EXE则调用它将调用.我想构建NODE.DLL它以便它静态链接到O.DLL公司C.但问题是,一旦M.EXE运行,它已加载U.DLL\S\BIN,并且符号\S\BIN\U.DLL略有不同\C\BIN\U.DLL,因为U.DLL每个构建的方式如何公司.因此,当M.EXE尝试加载时NODE.DLL,它会失败,因为当需要NODE.DLL加载时O.DLL,需要U.DLL的符号\C\BIN\U.DLL不存在,因为Windows看到U.DLL已经加载了.

情况图如下:

M.EXE static link to -> \S\BIN\U.DLL
M.EXE dynamic link to -> NODE.DLL
NODE.DLL static link to  O.DLL
O.DLL static link to \C\BIN\U.DLL
Run Code Online (Sandbox Code Playgroud)

实际上,我需要两者\S\BIN\U.DLL\C\BIN\U.DLL在同一个进程空间中共存,并M.EXE使用其版本U.DLLO.DLL使用其版本U.DLL.

请注意,我没有重建M.EXEO.DLL更改每次加载方式的选项U.DLL.它们来自第三方,因此无法更改静态链接.我也没有选择使用LoadLibraryon O.DLL,因为它是一个C++库,提供了一个导入库.

我认为,清单可以使用,这样当我建立NODE.DLL静态链接到O.DLL,我做一些事情,在清单中NODE.DLL,使O.DLL加载其自身的副本U.DLL是安装在\C\BIN\U.DLL.我只是无法弄清楚如何做到这一点.理想情况下,我不想修改清单O.DLL,但如果这是唯一的解决方案,我会接受它.

ssu*_*ube 4

通过使用绝对路径加载一个或多个DLL,可以在同一进程中拥有多个具有相同文件名的 DLL。这确实需要动态加载 DLL,但其他方面的行为是相同的。

您不需要在构建过程中进行链接,而是需要std::string moduleName = appPath + "\s\bin\u.dll"; LoadModule(moduleName.c_str()). 因为这对于需要加载哪个 DLL 是明确的,所以它允许您加载多个具有“相同”名称的 DLL。

加载模块后,您可以将每个必要的函数分配给函数指针,然后包装它们或使用合法但很少使用的语法将函数指针作为普通函数调用funcPtr(params))。

如果您使用的是更新版本的 Windows,则可以使用 DLL 清单来加强模块的版本控制/命名,并使 EXE 加载与通常情况不同的 DLL。我不熟悉这到底是如何完成的,尽管 MSDN 上有记录(也可能在这里)。