如何将__stdcall dll与未修饰的导出链接到__cdecl二进制文件?

时间:2017-03-03 09:14:03

标签: c++ qt dll linker

我的32位Windows程序使用默认的__cdecl调用约定。它正在使用Qt工具包。我正在尝试使用使用__stdcall约定的unamanged 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中重命名导出吗? : - )

1 个答案:

答案 0 :(得分:0)

问题不在于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。