具有相同名称的非托管C ++ DLL同时存在于同一进程中 [英] Unmanaged C++ DLL's with same name coexisting in same process

查看:109
本文介绍了具有相同名称的非托管C ++ DLL同时存在于同一进程中的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

Using Visual Studio c++ V10, I am trying to figure out how to build a DLL and resolve a DLL naming conflict. Here are the details.

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

Company S ships a product called M.EXE. Assume that M.EXE is installed in \S\BIN\M.EXE. Company S statically links to a DLL called U.DLL, which is installed in \S\BIN\U.DLL. U.DLL contains open source code, and is built with Visual C++ compiler options /Zc:wchar_t-, which doesn't recognize wchar as a native type.

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

Company C ships a DLL called O.DLL, and publishes the API's for this DLL, and ships an import library for O.DLL. Assume that O.DLL is installed in \C\BIN\O.DLL. O.DLL statically links to a DLL called U.DLL, which is installed in \C\BIN\U.DLL. U.DLL is built on the same open source code, but is built with Visual C++ compiler options /Zc:wchar_t, which does recognize wchar_t as a native type.

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

Ideally Company C and Company S would agree to build U.DLLusing the same Visual C++ options, but that is not possible.

M。公司S的EXE 是可扩展的,因为我可以在非托管C ++中构建自己的DLL,调用 NODE.DLL > M.EXE 将调用,如果我正确设置一切。我想建立 NODE.DLL ,以便它静态链接到C公司的 O.DLL 。但问题一旦 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 from Company S is extensible, in that I can build my own DLL in unmanaged C++, call it NODE.DLL that M.EXE will invoke if I set everything up correctly. I would like to build NODE.DLL so that it statically links to O.DLL from Company C. But the problem is that once M.EXE is running, it has loaded the U.DLL library from \S\BIN, and the symbols from \S\BIN\U.DLL are slightly different than the ones in \C\BIN\U.DLL, because of how U.DLL was built by each company. So when M.EXE attempts to load NODE.DLL, it fails, because when NODE.DLL loads O.DLL, which needs U.DLL, the symbols needed from \C\BIN\U.DLL are not there, because Windows sees U.DLL as already being loaded.

情况图如下:

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

有效地,我需要 \S\BIN\U.DLL \C\BIN\U.DLL 在同一个进程空间中共存,并且拥有 M.EXE 版本 U.DLL O.DLL 使用其版本 U.DLL

Effectively, I need both \S\BIN\U.DLL and \C\BIN\U.DLL to co-exist in the same process space, and have M.EXE use its version of U.DLL and O.DLL use its version of U.DLL.

请注意,我没有选择重建 M.EXE O.DLL 以更改它们各自加载 U.DLL 的方式。它们来自第三方,因此静态链接不能更改。我也没有在 O.DLL 上使用 LoadLibrary 的选项,因为它是一个C ++库,提供与导入库。

Note that I do not have the option to rebuild M.EXE or O.DLL to change how they each load U.DLL. They come from third parties, so the static linking can't be changed. I also don't have the option of using LoadLibrary on O.DLL, because it is a C++ library, provided with an import library.

我相信可以使用清单,以便当我构建静态链接到O的 NODE.DLL DLL,我在 NODE.DLL 的清单中设置,以便 O.DLL 加载自己的<安装在 \C\BIN\U.DLL 中的code> U.DLL 。我只是不知道如何做到这一点。理想情况下,我不想修改 O.DLL 的清单,但如果这是唯一的解决方案,我就会这样。

I believe that manifests can be used so that when I build NODE.DLL that is statically linked to O.DLL, I set things up in the manifest of NODE.DLL so that O.DLL loads its own copy of U.DLL that is installed in \C\BIN\U.DLL. I just cannot figure out how to do this. Ideally, I'd like to not modify the manifest of O.DLL, but if that is the only solution, I'll live with that.

推荐答案

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

You can have multiple DLLs with the same filename in the same process by loading one or more of them with absolute paths. This does require the DLL to be dynamically loaded, but behavior is otherwise identical.

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

Instead of linking during the build process, you need to std::string moduleName = appPath + "\s\bin\u.dll"; LoadModule(moduleName.c_str()). Because this is unambiguous as to which DLL needs loaded, it allows you to load multiple ones with the "same" name.

一旦你有模块加载,你可以分配每个函数指针的必要函数,然后打包或使用合法但很少使用的调用函数指针作为正常函数的语法 funcPtr(params))。

Once you have the module loaded, you can assign each of the necessary functions to function pointers, then either wrap those or use the legal but little-used syntax of calling functions pointers as normal functions (funcPtr(params)).

在最新版本的Windows上,您可以使用DLL清单来加强模块的版本/命名,并导致EXE加载与其通常情况不同的DLL。我不太熟悉这是怎么做的,虽然它记录在MSDN上(也可能在这里)。

If you are on a more recent version of Windows, you may be able to use DLL manifests to strengthen the versioning/naming around the module and cause the EXE to load a different DLL than it typically would. I'm not familiar with how exactly this would be done, although it is documented on MSDN (and probably here as well).

这篇关于具有相同名称的非托管C ++ DLL同时存在于同一进程中的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆