mingw32 g ++ и stdcall @suffix - PullRequest
       50

mingw32 g ++ и stdcall @suffix

1 голос
/ 09 ноября 2011

Я объявил некоторые функции C ++ прототипированными следующим образом:

extern "C" void __stdcall function();

У меня также есть сторонние dll с экспортированным function() - без именных украшений вообще.Я не могу собрать свой exe или dll из-за undefined reference to function@... из-за stdcall @ -suffix из MinGW.Как получить объектный файл без @ ... просто имен функций?

Ответы [ 2 ]

6 голосов
/ 27 января 2012

Похоже, вы пытаетесь использовать MinGW для компиляции программы, которая использует внешние функции C из сторонней библиотеки dll.Есть способ экспортировать эти внешние функции в правильную библиотеку импорта, которую может использовать компоновщик MinGW gnu ld, но это включает создание файла определения .def.Преимущество этого заключается в том, что после того, как вы создадите правильную библиотеку импорта, вам не придется возиться с переключателями типа --add-stdcall-alias или --kill-at, потому что библиотека импорта будет содержать символы, ожидаемые компилятором и компоновщиком.

Вот примерный план процедуры для этого:

  1. Вам потребуется вызов инструмента dlltool.exe, который должен быть включен в тот же каталог MinGW/bin, что и компилятор.
  2. Вам нужно создать файл определения (* .def), в котором перечислены все внешние функции, которые вы хотите импортировать.
  3. Создайте заглушку файла импорта (* .a), запустив dlltool, передавая.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, которую вы уже видели.Конечным результатом этого является то, что у вас есть библиотека импорта с правильным внутренним украшением имени, поэтому все разрешается правильно, и , это внутреннее имя будет сопоставляться с экспортированным видимым именем, найденным в вашем 3 rd party 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

Вы должны убедиться, что соглашения о вызовах соответствуютили рискуете испортить стек и загадочные сбои программы.

3 голосов
/ 09 ноября 2011

man ld дает вам опцию --enable-stdcall-fixup для связывания с библиотеками без @.Я не уверен, будут ли проблемы с ведущими подчеркиваниями, вам придется попробовать.

Если вы хотите создавать объектные файлы или библиотеки DLL с mingw и хотите экспортировать имена без «@», --kill-at твой друг.

...