c++ - mingw32 g++ 和 stdcall @suffix

标签 c++ linker mingw name-decoration stdcall

我声明了一些 C++ 函数原型(prototype)如下:

extern "C" void __stdcall function();

我还有一些带有导出 function() 的第三方 dll - 根本没有名称修饰。 由于 undefined reference to function@...,由于 MinGW 的 stdcall @-suffix,我无法构建我的 exe 或 dll。如何在没有 @... 的情况下获取目标文件,只是简单的函数名称?

最佳答案

听起来您正在尝试使用 MinGW 编译一个使用来自第三方 dll 的外部 C 函数的程序。有一种方法可以将这些外部函数导出到 MinGW 的 gnu ld 链接器可以使用的适当导入库中,但它涉及创建一个 .def 定义文件。这样做的好处是,一旦你创建了一个合适的导入库,你就不必摆弄像 --add-stdcall-alias--kill-at 这样的开关因为导入库将包含编译器和链接器所需的符号。

这是执行此操作的大致过程:

  1. 您需要一个名为 dlltool.exe 的工具,它应该包含在与编译器相同的 MinGW/bin 目录中。
  2. 您需要创建一个定义文件 (*.def),列出您有兴趣导入的所有外部函数。
  3. 通过运行 dlltool 并传入您创建的 .def 文件作为输入来创建导入文件 stub (*.a)。
  4. 在构建项目时将新创建的导入文件 *.a 传递给链接器,以便正确解析符号。

这是定义文件的样子:

;Run the dlltool like this:
;dlltool -k -d third_party.def -l libthird_party.a
LIBRARY third_party.dll

EXPORTS
    dll_function1@0
    dll_function2@8
    dll_function3@16
;   ...
    dll_function_n@24

需要注意几件重要的事情。 EXPORTS 部分必须按照工具链的预期以相同的名称装饰格式列出导出的符号/函数。在这种情况下,MinGW 编译器和 ld 链接器期望 __stdcall C 函数附加一个“@”,后跟参数中的字节数。需要注意的第二个重要事项是 dlltool -k 将删除“@”,这与您已经看到的 --kill-at 选项的作用相同.这样做的最终结果是您拥有一个带有正确内部名称修饰的导入库,因此可以正确解析,并且该内部名称将映射到您的第 3rd 中导出的可见名称 派对 dll。

最后一件事需要提及。在整个示例中,我们假设 dll 中未修饰的名称使用了 __stdcall,但这不一定是真的。下图 ( taken from here ) 显示了不同的编译器如何以不同的方式修饰 __cdecl__stdcall:

                  MSVC DLL
Call Convention | (dllexport) | DMC DLL     | MinGW DLL  | BCC DLL
----------------------------------------------------------------------------
__stdcall       | _Function@n | _Function@n | Function@n | Function
__cdecl         | Function    | Function    | Function   | _Function

确保调用约定正确匹配或冒堆栈损坏和神秘程序崩溃的风险取决于您。

关于c++ - mingw32 g++ 和 stdcall @suffix,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8063842/

相关文章:

c++ - Visual Studio - 过滤掉 nvcc 警告

c++ - Windows 上使用 C++ 的 google protobuf 时间戳未声明的标识符

c++ - 模板特化,Windows 与 gcc 上的不同行为?

c++ - 如何将gsl添加到MinGW?

C++ - 覆盖以前输出到控制台的多行

c++ - 垃圾收集的想法

c++ - 尝试将记录中的数据读入程序时难以捉摸的错误(C++)

c++ - Visual Studio强制在项目的所有编译单元中包含预编译头文件?

c++ - MS visual studio 2013 SDL 不工作

gcc - 使用 MinGW64 gcc 构建 GLFW -- 入口符号警告和链接器错误