我不明白为什么我使用该地址调用CreateFileA
函数会导致程序崩溃。
此摘录应使用从CreateFileA
调用中获取的地址来调用GetProcAddress
。当然,在这个简单的示例中,我可以正常地调用它,但是我需要手动检索每个地址(即使是LoadLibraryA
和GetProcAddress
,但为了简洁起见,我在此示例中都没有)>
我在做什么错?为什么如果我在最后一行使用CreateFileA
而不是(*CreateFileAAddr)
,即使他们指向同一件事,它也可以工作?
#include <windows.h>
typedef HMODULE(*_LoadLibraryA)(LPCSTR);
typedef FARPROC(*_GetProcAddress)(HMODULE, LPCSTR);
typedef HANDLE(*_CreateFileA)(LPCSTR, DWORD, DWORD, LPSECURITY_ATTRIBUTES, DWORD, DWORD, HANDLE);
int main() {
_LoadLibraryA LoadLibraryAAddr = (_LoadLibraryA)&LoadLibraryA;
_GetProcAddress GetProcAddressAddr = (_GetProcAddress)&GetProcAddress;
HMODULE kernel32Handle = (*LoadLibraryAAddr)("Kernel32.dll");
if (kernel32Handle == NULL) return -1;
_CreateFileA CreateFileAAddr = (_CreateFileA)((*GetProcAddressAddr)(kernel32Handle, "CreateFileA"));
if ((unsigned long)CreateFileAAddr != (unsigned long)&CreateFileA) return -1; //Just to check if the address is correct for Debug
(*CreateFileAAddr)("123.txt", GENERIC_WRITE, 0, NULL, OPEN_ALWAYS, OPEN_ALWAYS, NULL);
return 0;
}
答案 0 :(得分:1)
根据我的评论,Windows API函数和指向该函数的指针类型需要用__stdcall
(或WINAPI
)注释,这会将它们的调用约定更改为API期望的调用约定(有关stdcall调用约定here的更多信息。
typedef HMODULE(__stdcall *_LoadLibraryA)(LPCSTR);
typedef FARPROC(__stdcall *_GetProcAddress)(HMODULE, LPCSTR);
typedef HANDLE(__stdcall *_CreateFileA)(LPCSTR, DWORD, DWORD, LPSECURITY_ATTRIBUTES, DWORD, DWORD, HANDLE);
另外请注意:出于某种原因,必须将*
放在__stdcall
之后;否则注释将无济于事。