Имя Stdcall Mangling с использованием Extern C и Dllexport vs Определения модулей (MSVC ++)
-
13-10-2019 - |
Вопрос
Я пытался экспортировать простую тестовую функцию для работы DLL для работы с приложением (к вашему сведению: MIRC), которое указывает вызову соглашения как:
int __stdcall test_func(HWND mWnd, HWND aWnd, char *data, char *parms, BOOL show, BOOL nopause)
Теперь, чтобы назвать это из приложения, я буду использовать test_func Но я заметил, что из -за того, что имени умочительно, оно не так просто, как я подумал.
Через аналогичные темы я пришел к пониманию, что использование Внешний "C" в комбинации с __declspec (dllexport) является эквивалентным (несколько) методом удаления искажения в определениях модулей (.def). Однако при использовании метода Extern/dllexport моя функция (в качестве примера) всегда _test_func@номера в то время как .def удалил все, как требуется для использования с приложением, которое мне нужно было экспортировать.
Может ли кто -нибудь объяснить, почему это? Мне просто любопытно о двух методах. Спасибо!
Решение
Dllexport/Import предназначен для загрузки сами по себе, а не старой библиотеки C с использованием GetProcadDress. Чужая, которое вы видели, - это то, что все компиляторы Microsoft делали в течение долгого времени для функций __stdcall. Скорее всего, ваша цель либо ожидает функции __CDECL, а не __stdcall, но если нет, вам нужно будет использовать файл .def, чтобы специально разоблачить имя.
Другие советы
extern "C"
не имеет ничего общего с STDCALL: он только заявляет, что имя C ++ Mangling (он же тип-безопасная связь; включение информации типа в имя символа) отключено. Вам необходимо использовать его независимо от того, используете ли вы Конвенцию о вызовах C -вызова или Cl
В конвенции STDCALL вызов Callee удаляет параметры из стека. Чтобы сделать это безопасным, экспортируемое имя содержит количество байтов, которые Callee удалит из стека.
Если приложение, которое вы экспортируете, требует, чтобы нет @number
Суффикс добавляется к названию, это, вероятно, означает, что он ожидает C -вызовов. Итак, вы должны перестать объявлять функцию __stdcall
. Анкет Когда вы объявите это как declspec(dllexport)
, вы должны получить необеспеченное имя в DLL.
В файле DEF вы можете вызвать функцию, что захотите; Дополнительная проверка не выполнена.