gpt4 book ai didi

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

转载 作者:太空宇宙 更新时间:2023-11-03 10:20:17 24 4
gpt4 key购买 nike

我声明了一些 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/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com