mingw32 g ++和stdcall @后缀 [英] mingw32 g++ and stdcall @suffix

查看:384
本文介绍了mingw32 g ++和stdcall @后缀的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我声明了一些C ++函数的原型,如下所示:

I declared some C++ functions prototyped as follows:

extern "C" void __stdcall function();

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

I also have some third-party dll with exported function() - no name decorations at all. I'm unable to build my exe or dll due to undefined reference to function@..., because of MinGW's stdcall @-suffix. How can I obtain object file without @... just plain function names?

推荐答案

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

It sounds like you're trying to use MinGW to compile a program that uses external C functions from a third-party dll. There's a way to export those external functions into a proper import library that MinGW's gnu ld linker can use but it involves creating a .def definition file. The advantage with this is once you create a proper import library you won't have to fiddle around with switches like --add-stdcall-alias or --kill-at because the import library will contain the symbols expected by the compiler and linker.

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

Here's a rough outline of the procedure for doing this:

  1. 您需要一个工具调用dlltool.exe,该工具调用应包含在与编译器相同的MinGW/bin目录中.
  2. 您需要创建一个定义文件(* .def),其中列出了您要导入的所有外部函数.
  3. 通过运行dlltool传入创建的.def文件作为输入来创建导入文件存根(* .a).
  4. 在构建项目时将新创建的导入文件* .a传递给链接器,以便可以正确解析符号.
  1. You'll need a tool call dlltool.exe which should be included in the same MinGW/bin directory as the compiler.
  2. You'll need to create a definition file (*.def) listing all the external functions you're interested in importing.
  3. Create the import file stub (*.a) by running dlltool passing in the .def file you created as input.
  4. Pass the newly created import file *.a to the linker when building your project so the symbols can be resolved properly.

定义文件的外观如下:

;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选项相同.最终的结果是,您拥有一个具有正确内部名称修饰的导入库,因此事情可以正确解决,并且内部名称将映射到在您的3 rd中找到的导出的可见名称. 派对dll.

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.

最后一件事需要提及.在整个示例中,我们假定 dll中未修饰的名称使用了__stdcall,但这不一定是正确的.下图(从此处获取)显示了不同的编译器如何用不同的方式修饰__cdecl__stdcall:

One final thing that needs mentioning. Throughout the entire example, we were assuming the undecorated names in the dll used the __stdcall which isn't necessarily true. The following chart(taken from here) shows how different compilers decorate __cdecl vs __stdcall differently:

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

由您决定调用约定是否正确匹配,否则可能会导致堆栈损坏和神秘的程序崩溃.

It's up to you to make sure that the call conventions match-up properly or risk stack corruption and mysterious program crashes.

这篇关于mingw32 g ++和stdcall @后缀的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆