C++ DLL 函数导出。 DLL 不保持加载状态
您好,我遇到以下问题,我无法弄清楚发生了什么。
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?
预先感谢大家。
编辑:
我已按照c-smile的建议用DLL_PROCESS_DETACH替换了DLL_THREAD_ATTACH。我检查并导出函数为:long __stdcall HookProc(int,unsigned int,long) (1)(0x00001000)。 GetProcAddress() 仍然失败。我收到“DLL 已加载”、GetProcAddress() 失败、“DLL 已卸载”
hi I've got the following problem, and I cannot figure out what is going on.
DLL code 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;
}
Program code 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;
}
Both files compile without any errors. Whenever I run my_prog.exe it would give a message "DLL Loaded", then right away It would give message "DLL unloaded" and, as a result, GetProcAddress() fails. Could someone shine some light on it for me please. Why does it unload the DLL instantaneously?
Thank you all in advance.
EDITED:
I've replaced DLL_THREAD_ATTACH by DLL_PROCESS_DETACH as c-smile suggested. I check and function exports as: long __stdcall HookProc(int,unsigned int,long) (1)(0x00001000). GetProcAddress() still fails. I get "DLL Loaded", GetProcAddress() failed, "DLL Unloaded"
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
DLL_THREAD_ATTACH
替换为DLL_PROCESS_DETACH
DLL_THREAD_ATTACH
byDLL_PROCESS_DETACH
有两件事:
由于这是一个 C++ 编译单元,因此您的导出将具有损坏的名称
?HookProc@@YGJHIJ@Z
- 这就是为什么GetProcAddress(hInstDLL, "HookProc")
失败 - 这不是正确的名称。使用
您将获得一个更易于管理的名称
_HookProc@12
,因此GetProcAddress(hInstDLL, "_HookProc@12")
应该可以工作。如果您想要一个更好的名称,我认为您需要使用 DEF 文件,来自 http://msdn.microsoft.com/en-us/library/3y1sfaz2.aspx:
像下面这样的 .def 文件应该可以解决问题(注意:
EXPORTS
关键字似乎区分大小写):使用
/def:whatever.def 将 .def 文件传递给链接器
选项。Two things:
DLL_THREAD_ATTACH
means things are going wrong. It's something that should happen when something links to your DLL as c-smile said.Since this is a C++ compilation unit, your export will have the mangled name
?HookProc@@YGJHIJ@Z
- that's whyGetProcAddress(hInstDLL, "HookProc")
fails - it's not the right name.Use
And you'll get a more manageable name of
_HookProc@12
, soGetProcAddress(hInstDLL, "_HookProc@12")
should work.If you want an even nicer name, I think you'll need to use a DEF file, From http://msdn.microsoft.com/en-us/library/3y1sfaz2.aspx:
A .def file like the following should do the trick (note: the
EXPORTS
keyword seems to be case sensitive):Pass the .def file to the linker using the
/def:whatever.def
option.您可以尝试使用
printf
代替MessageBox
吗?MessageBox
是模态的,它可能会把事情搞砸。Instead of
MessageBox
, can you tryprintf
?MessageBox
is modal and it is probably messing things up.在 DLL 代码中,当使用 DLL_PROCESS_DETACH 时:
“lpReserved 参数指示 DLL 是否由于 FreeLibrary 调用、加载失败或进程终止而被卸载。”
所以我会检查该参数,它可能有助于缩小问题范围。
我还将检查 LoadLibrary 的返回值以确保实际加载成功。如果 LoadLibrary 失败,您可以尝试使用“GetLastError()”API 获取更多信息。
另外,您没有执行“FreeLibrary(hInst);”在你的 LoadLibrary 之后。
In the DLL code, when using DLL_PROCESS_DETACH:
"The lpReserved parameter indicates whether the DLL is being unloaded as a result of a FreeLibrary call, a failure to load, or process termination."
So I would check that parameter, it might help narrow down the problem.
I would also be checking the return value of LoadLibrary to make sure the actual Load succeeded. If the LoadLibrary is failing you can try using 'GetLastError()' API for more information.
Also you are not doing a 'FreeLibrary(hInst);' after your LoadLibrary.