имя stdcall искажение с использованием extern c и dllexport vs определения модулей (msvc++)

Я пытался экспортировать простую тестовую функцию для dll для работы с приложением( fyi: mIRC), которое определяет соглашение о вызове как:

int __stdcall test_func(HWND mWnd, HWND aWnd, char *data, char *parms, BOOL show, BOOL nopause)

теперь, чтобы вызвать это из приложения, я бы использовал test_func но я заметил, что из-за искажения имени это не так просто, как я думал.

через аналогичные темы здесь я пришел к пониманию, что использование extern "C" в сочетании с _ _ declspec (dllexport) - это эквивалент (несколько) метод удаления коверканье в модуле определений (.DEF.) Однако при использовании метода extern/dllexport моя функция (в качестве примера) всегда _test_func@numbers в то время как .def удалил все повреждения, необходимые для использования с приложением, в которое мне нужно было экспортировать.

может кто-нибудь объяснить, почему это? Мне просто любопытны эти два метода. Спасибо!

2 ответов


dllexport / import предназначены для загрузки обратно сами по себе, а не старая библиотека C с помощью GetProcAddress. Искажение, которое вы видели, - это то, что все компиляторы Microsoft долгое время делали для функций __stdcall. Скорее всего, ваша цель либо ожидает функцию _ _ cdecl, а не __stdcall, но если нет, вам нужно будет использовать a .def-файл, чтобы специально удалить имя.


extern "C" не имеет ничего общего с stdcall: он только объявляет, что c++ name mangling (aka type-safe linkage; включение информации о типе в имя символа) отключено. Вы должны использовать его независимо от того, используете ли вы соглашение о вызовах C или соглашение о вызовах stdcall.

в соглашении о вызове stdcall вызываемый объект удаляет параметры из стека. Чтобы сделать это безопасным, экспортированное имя содержит количество байтов, которые вызываемый объект удалит из стек.

если приложение, которое вы экспортируете, требует, чтобы нет @number суффикс добавляется к имени, это, вероятно, означает, что он ожидает, что соглашение о вызове c. Поэтому вы должны прекратить объявлять функцию как __stdcall. Когда вы объявляете это как declspec(dllexport), вы должны получить undecorated имя в DLL.

в файле DEF вы можете вызвать функцию, какую захотите; дополнительная проверка не выполняется.