简体   繁体   中英

mingw32 g++ and stdcall @suffix

I declared some C++ functions prototyped as follows:

extern "C" void __stdcall function();

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?

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. 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.

Here's how the definition file looks like:

;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 3 rd party dll.

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.

man ld gives you the --enable-stdcall-fixup option for linking against non-@-decorated libraries. I'm not sure if the leading underscores will be a problem, you'll have to try.

If you want to produce object files or DLLs with mingw and want export names without the "@", --kill-at is your friend.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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