在动态加载的 dll 中查找名称损坏的函数

Posted

技术标签:

【中文标题】在动态加载的 dll 中查找名称损坏的函数【英文标题】:Find name-mangled function in dynamically-loaded dll 【发布时间】:2014-04-26 18:11:11 【问题描述】:

我有一组明确设计为仅在 C++ 中使用的 API。我不希望它们被 C 程序(或任何其他语言)使用,因此我导出命名空间和类信息,而不是使用 extern "C" 路由并使用内联实用程序函数调用普通 C功能。

现在我只处理在编译时链接的 dll,这意味着将函数导入可执行文件非常容易,因为它不涉及我的任何工作。但是,我计划开发一个插件系统,它需要我在运行时动态加载 dll。我能否使用GetProcAddress() 找到名称损坏的 C++ 函数?

【问题讨论】:

【参考方案1】:

你正在做的是not necessarily a good idea,除非你控制整个构建链并且可以确保你的 DLL 和使用它的任何应用程序都是使用相同版本的相同编译器构建的。

话虽如此,是的,您可以使用GetProcAddress 加载名称损坏的函数。只需使用Dependency Walker 或查看为您的 DLL 生成的 .def 文件,如果您的编译器设置为生成一个,以获取损坏的函数名称。然后你可以GetProcAddress它。但是,您不能使用未损坏的名称调用 GetProcAddress 并期望它找到正确的损坏名称。例如,如果您的 DLL 函数名为 Add,并被修改为 _Z3Addv,则您需要调用 GetProcAddress(myDLL, "_Z3Addv"); 才能正确访问该函数。

每次更改函数的声明时,都需要将调用更改为GetProcAddress,因为损坏的名称也会更改。请注意,如果您更改构建 DLL 的编译器,您还需要更改 GetProcAddress 调用 - MSVC 的重整与 GCC 有很大不同,而 clang 的重整可能​​与它们两者都不同。因此,您可能需要重新考虑执行此操作的方式,因为它似乎很容易在此过程中的某个地方中断。

【讨论】:

继续允许对编译时链接的 dll 进行名称修改,并修饰您链接的问题,将对象传入和传出它是否安全? dll 及其链接的可执行文件将始终使用相同的编译器构建。 如果您链接到 DLL,名称修改应该是无关紧要的,因为编译器会自动调整您的 EXE 进行的任何调用以访问 DLL 中的正确函数。只要您确定,您将始终使用同一编译器的相同版本构建 DLL 和任何调用 EXE,您应该能够安全地将对象传入和传出 DLL . 当然,没有人可以保证代码总是由相同的编译器构建:代码继续存在,程序员继续前进,新程序员进来,组织目标转移,公司被出售等等。完全令人惊讶的是代码的寿命,通常超过其创建者最疯狂的期望。

以上是关于在动态加载的 dll 中查找名称损坏的函数的主要内容,如果未能解决你的问题,请参考以下文章

C#中如何动态加载和卸载DLL

C#中动态加载和卸载DLL

动态加载vs静态加载

VC++ 解决dll库动态库加载失败问题(调用LoadLibrary加载失败)(附源码)

动态链接库的加载

AppDomain 详解二-C#中动态加载和卸载DLL