0

嗨,我遇到了以下问题,我无法弄清楚发生了什么。

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_THREAD_ATTACH 替换为 DLL_PROCESS_DETACH 。我检查并导出函数为:long __stdcall HookProc(int,unsigned int,long) (1)(0x00001000)。GetProcAddress() 仍然失败。我得到“DLL 加载”,GetProcAddress() 失败,“DLL 卸载”

4

4 回答 4

2
  1. 替换DLL_THREAD_ATTACHDLL_PROCESS_DETACH
  2. 确保您的函数完全导出为“HookProc”。
  3. 如果没有使用 .def 文件来定义函数的导出名称。
于 2011-05-25T05:27:13.707 回答
1

两件事情:

  1. 不要认为这DLL_THREAD_ATTACH意味着事情正在出错。正如 c-smile 所说,当某些东西链接到您的 DLL 时,应该会发生这种情况。
  2. 由于这是一个 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")应该可以工作。

如果您想要一个更好的名称,我认为您需要使用来自http://msdn.microsoft.com/en-us/library/3y1sfaz2.aspx的 DEF 文件:

C++ 函数的 dllexport 将公开具有 C++ 名称修饰的函数。如果不需要 C++ 名称修改,请使用 .def 文件(EXPORTS 关键字)或将函数声明为 extern "C"。

像下面这样的 .def 文件应该可以解决问题(注意:EXPORTS关键字似乎区分大小写):

EXPORTS
    HookProc=_HookProc@12

/def:whatever.def使用该选项将 .def 文件传递​​给链接器。

于 2011-05-25T06:06:34.293 回答
0

代替MessageBox,你可以试试printf吗?MessageBox是模态的,它可能把事情搞砸了。

于 2011-05-25T05:43:42.453 回答
0

在 DLL 代码中,使用 DLL_PROCESS_DETACH 时:

“lpReserved 参数指示 DLL 是否由于 FreeLibrary 调用、加载失败或进程终止而被卸载。”

所以我会检查那个参数,它可能有助于缩小问题的范围。

我还将检查 LoadLibrary 的返回值,以确保实际加载成功。如果 LoadLibrary 失败,您可以尝试使用“GetLastError()”API 获取更多信息。

你也没有做'FreeLibrary(hInst);' 在您的 LoadLibrary 之后。

于 2011-05-25T06:05:31.473 回答