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

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

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

【问题讨论】:

    标签: c++ c windows visual-studio dll


    【解决方案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 .
    • 当然,没有人可以保证代码总是由相同的编译器构建:代码继续存在,程序员继续前进,新程序员进来,组织目标转移,公司被出售等等。完全令人惊讶的是代码的寿命,通常超过其创建者最疯狂的期望。
    猜你喜欢
    • 2020-07-07
    • 2016-03-18
    • 1970-01-01
    • 2012-01-31
    • 1970-01-01
    • 2012-11-20
    • 2019-07-20
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多