您好,我遇到了以下问题,我无法弄清楚是怎么回事。
DLL代码mylib.cpp(mylib.dll):
#include <Windows.h>
#include <tchar.h>
__declspec(dllexport) LRESULT CALLBACK HookProc(int nCode, WPARAM wParam, LPARAM lParam) {
return CallNextHookEx(NULL, nCode, wParam, lParam);
}
BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserverd){
// Perform actions based on the reason for calling.
switch( fdwReason )
{
case DLL_PROCESS_ATTACH:
// Initialize once for each new process.
// Return FALSE to fail DLL load.
MessageBox(NULL,
_T("DLL Loaded"),
_T("DLL Loaded"),
NULL);
break;
case DLL_THREAD_ATTACH:
// Do thread-specific initialization.
MessageBox(NULL,
_T("DLL Unloaded"),
_T("DLL Unloaded"),
NULL);
break;
}
return TRUE;
}
程序代码my_prog.cpp:
#include <Windows.h>
#include <tchar.h>
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow){
FARPROC pHookProc;
static HINSTANCE hInstDLL;
hInstDLL = LoadLibrary(_T("mylib.dll"));
pHookProc = GetProcAddress(hInstDLL, "HookProc");
if (!pHookProc) {
MessageBox(NULL,
_T("GetProcAddress failed"),
_T("GetProcAddress failed"),
NULL);
}
return 0;
}
这两个文件都编译没有任何错误。每当我运行my_prog.exe时,它将给出消息“ DLL Loaded”,然后立即给出消息“ DLL unloaded”,结果GetProcAddress()失败。有人能帮我照一下吗。为什么它会立即卸载DLL?
谢谢大家。
编辑:
我已将DLL_THREAD_ATTACH替换为DLL_PROCESS_DETACH,如c-smile建议。我检查并将函数导出为:long __stdcall HookProc(int,unsigned int,long)(1)(0x00001000)。 GetProcAddress()仍然失败。我收到“ DLL已加载”,GetProcAddress()失败,“ DLL已卸载”
最佳答案
两件事情:
不要以为DLL_THREAD_ATTACH
表示事情出了问题。当某些链接到您的DLL as c-smile said时,应该发生这种情况。
由于这是C ++编译单元,因此您的导出将具有错误的名称?HookProc@@YGJHIJ@Z
-这就是GetProcAddress(hInstDLL, "HookProc")
失败的原因-它不是正确的名称。
使用
extern "C" __declspec(dllexport) LRESULT CALLBACK HookProc(int nCode, WPARAM wParam, LPARAM lParam);
而且您会得到一个更易于管理的名称
_HookProc@12
,因此GetProcAddress(hInstDLL, "_HookProc@12")
应该可以工作。如果您想要一个更好的名称,我想您需要使用DEA文件,来自http://msdn.microsoft.com/en-us/library/3y1sfaz2.aspx:
C ++函数的dllexport将使用C ++名称修饰公开该函数。如果不需要C ++名称修饰,请使用.def文件(EXPORTS关键字)或将函数声明为extern“ C”。
如下所示的.def文件应该可以解决问题(注意:
EXPORTS
关键字似乎区分大小写):EXPORTS
HookProc=_HookProc@12
使用
/def:whatever.def
选项将.def文件传递到链接器。关于c++ - C++ DLL函数导出。 DLL不会保持加载状态,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/6119862/