我声明了一些原型化的 C++ 函数,如下所示:
extern "C" void __stdcall function();
我还有一些导出的第三方 dllfunction()
- 根本没有名字装饰。
由于以下原因,我无法构建我的 exe 或 dllundefined reference to function@...
,因为 MinGW 的 stdcall @-后缀。如何在没有@...的情况下获取目标文件,只是简单的函数名称?
听起来您正在尝试使用 MinGW 编译一个使用第三方 dll 中的外部 C 函数的程序。有一种方法可以将这些外部函数导出到 MinGW 的正确导入库中gnu ld
链接器可以使用,但它涉及创建一个.def
定义文件。这样做的好处是,一旦创建了正确的导入库,您就不必摆弄像这样的开关--add-stdcall-alias
or --kill-at
因为导入库将包含编译器和链接器期望的符号。
以下是执行此操作的过程的粗略概述:
- 您需要一个工具调用
dlltool.exe
应该包含在同一MinGW/bin
目录作为编译器。
- 您需要创建一个定义文件 (*.def),列出您有兴趣导入的所有外部函数。
- 通过运行 dlltool 并传入您创建的 .def 文件作为输入来创建导入文件存根 (*.a)。
- 在构建项目时将新创建的导入文件 *.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
Couple of important things to note. The EXPORTS
section has to list the exported symbols/functions in the same name-decorated format as expected by the toolchain. In this case, MinGW compiler and ld linker expects __stdcall
C functions to be appended with an '@' follow by the number of bytes in the arguments. The second important thing to note is that dlltool -k
will remove the '@', which does the same thing as the --kill-at
option you've already seen. The end result of this is you have an import library with the correct internal name-decoration, so things resolve properly, and that internal name will map to the exported visible name found in your 3rd party dll.
最后需要提及的一件事。在整个示例中,我们assumingdll 中未修饰的名称使用__stdcall
这不一定是真的。如下图(取自这里) 展示了不同编译器如何装饰__cdecl
vs __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
您需要确保调用约定正确匹配,否则将面临堆栈损坏和神秘程序崩溃的风险。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)