繁体   English   中英

mingw32 g++ 和 stdcall @suffix

[英]mingw32 g++ and stdcall @suffix

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

extern "C" void __stdcall function();

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

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

以下是执行此操作的过程的粗略概述:

  1. 您将需要一个工具调用dlltool.exe ,它应该包含在与编译器相同的MinGW/bin目录中。
  2. 您需要创建一个定义文件 (*.def),其中列出您有兴趣导入的所有外部函数。
  3. 通过运行 dlltool 来创建导入文件存根 (*.a),传入您创建的 .def 文件作为输入。
  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选项的作用相同。 这样做的最终结果是你有正确的内部名称装修的导入库,这样的事情解决不好,而且内部名称将映射到导出的可视名称在您的第三方DLL中。

需要提及的最后一件事。 在整个示例中,我们假设dll 中未修饰的名称使用了__stdcall ,这不一定是真的。 下图(取自此处)显示了不同的编译器如何以不同的方式装饰__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

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

man ld为您提供了--enable-stdcall-fixup选项,用于链接非@-decorated 库。 我不确定前导下划线是否会成为问题,您必须尝试。

如果您想使用 mingw 生成目标文件或 DLL 并希望导出名称不带“@”,则--kill-at是您的朋友。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM