Я пытаюсь импортировать функцию из неуправляемой DLL в проект C, создав файл .def с указанием функции, которую мне нужно использовать. Практикуюсь на функции WinAPI MessageBoxA
из user32.dll
. Это функция стандартного вызова, как и другие функции WinAPI. Вот как я создаю свой файл .def:
LIBRARY user32.dll
EXPORTS
_MessageBoxA@16
Затем я создаю из него .lib следующим образом: lib /def:"C:\Path\to\def\user32.def" /
out:"C:\path\to\project\user32-mb.lib"
, который успешно создает user32-mb.lib
и user32-mb.exp
. Затем в моем проекте C я делаю следующее:
#pragma comment(lib, "user32-mb.lib")
#ifdef __cplusplus
#define EXTERNC extern "C"
#else
#define EXTERNC
#endif
EXTERNC __declspec(dllexport) int __stdcall MessageBoxA(void *hWnd, char *lpText, char *lpCaption, int uType);
void main(){
MessageBoxA(0, "MessageBox test", "MessageBox test", 0x00000030L);
}
Однако при подключении выдает следующую ошибку:
error LNK2019: unresolved external symbol _MessageBoxA@16 referenced in function _main
Однако, когда я меняю объявление в .def на это:
LIBRARY user32.dll
EXPORTS
MessageBoxA
И измените прототип функции в моем коде C на cdecl
вместо stdcall
:
EXTERNC __declspec(dllexport) int __cdecl MessageBoxA(void *hWnd, char *lpText, char *lpCaption, int uType);
Окно сообщения действительно появляется, но сразу после закрытия выдает ошибку:
Run-Time Check Failure #0 - The value of ESP was not properly saved across a function call. This is usually a result of calling a function declared with one calling convention with a function pointer declared with a different calling convention.
Что указывает на то, что вызывать его с помощью cdecl
тоже плохая идея, так как для этого все-таки требуется stdcall
.
Вопрос в том, что я должен изменить в файле .def или в моем проекте, чтобы избежать как ошибок, так и правильно импортировать и вызывать функцию stdcall
?