【问题标题】:How to link __stdcall dll with undecorated exports into __cdecl binary? [duplicate]如何将 __stdcall dll 与未修饰的导出链接到 __cdecl 二进制文件中? [复制]
【发布时间】:2017-03-03 09:14:02
【问题描述】:

我的 32 位 Windows 程序使用默认的 __cdecl 调用约定。它正在使用 Qt 工具包。我正在尝试使用使用 __stdcall 约定并仅导出未修饰名称的未管理 dll。

dumpbin /exports library.dll
[...]
    00000000 characteristics
           0 time date stamp
        0.00 version
           1 ordinal base
         210 number of functions
         210 number of names

    ordinal hint RVA      name
[...]
          6   9D 0000361C OpenComm
[...]

我创建了带有修饰名称映射的 .def 文件:

EXPORTS
    _OpenComm@8=OpenComm

因此.lib 有以下导出(注意前面的双下划线):

__OpenComm@8

头文件包含(注意我必须放在那里以匹配.lib):

extern "C"
{
int __stdcall _OpenComm(char *com, int Baudrate);
}

程序编译得很好,但是当我尝试运行它时,运行时链接器给了我一个错误:

The procedure entry point _OpenComm@8 could not be located in the dynamic link library.

好的。 Dll 没有我的映射名称...我该如何解决这个问题?我可以在编译的 .dll 中重命名导出吗? :-)

【问题讨论】:

    标签: c++ qt dll linker


    【解决方案1】:

    问题不在于 DLL,而在于您生成 .lib 的方式以及编写头文件的方式。

    不要在头文件中为你的函数添加下划线。编译器/链接器工具链会自动处理符号中的下划线。

    试试

    extern "C"
    {
    int __stdcall OpenComm(char *com, int Baudrate);
    }
    

    如果您在构建 DLL 和 .lib 时使用它,现在 .def 文件应该看起来像这样:

    LIBRARY mylibrary
    EXPORTS
        OpenComm
    

    但由于您仅从 .def 文件生成 .lib,并且 dll 使用 stdcall,因此您需要更改您的 .def:

    LIBRARY mylibrary
    EXPORTS
        OpenComm@8 @6
    

    这将有效地生成一个导出_OpenComm@8 的.lib,并使您的exe 在您的dll 中调用带有序号6 的符号。请注意,如果您更新 DLL,则必须检查是否使用 dumpbin 更改了任何序数并相应地更新您的 .def。

    【讨论】:

    • 当我听从您的建议时,我在编译过程中遇到了链接问题:错误:LNK2019:未解析的外部符号 _OpenComm@8 在函数中引用...我的环境是 Qt 5.8 和 Visual Studio 2015
    • 试试__declspec(dllimport) int __stdcall OpenComm(char *com, int Baudrate);
    • 它没有帮助:nexus.obj:-1: error: LNK2019: unresolved external symbol __imp__OpenComm@8 referenced in function ...
    • @MariuszZieliński 我已经更新了我的答案,以考虑到 def 文件中的 __stdcall。我建议你看看wyw.dcweb.cn/stdcall.htm,这是一个很好的阅读主题。
    • 本杰明。作为记录 - 我没有写下你的答案。我不喜欢人们不发表评论就这样做。我无法修改我拥有的 .dll 文件。它包含未修饰的导出,实际上是 __stdcall 调用。问题是说服我的程序使用未修饰符号而不是 _name@number 对 dll 函数进行 __stdcall 调用。我可以通过使用 QLibrary 手动加载库来做到这一点,但它似乎不太优雅。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-03-19
    • 1970-01-01
    • 2014-08-13
    • 2015-02-27
    • 2020-07-16
    • 1970-01-01
    • 2020-07-13
    相关资源
    最近更新 更多