C ++ DLL函数导出。 DLL不会保持加载状态

时间:2011-05-25 05:20:08

标签: c++ visual-c++ dllexport

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

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 Loaded”,GetProcAddress()失败,“DLL Unloaded”

4 个答案:

答案 0 :(得分:2)

  1. DLL_THREAD_ATTACH替换为DLL_PROCESS_DETACH
  2. 确保您的功能完全按“HookProc”导出。
  3. 如果没有使用.def文件来定义函数的导出名称。

答案 1 :(得分:1)

两件事:

  1. 不要以为DLL_THREAD_ATTACH表示事情出错了。当某些东西链接到您的DLL as c-smile said时,应该发生。
  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")应该有效。

  3. 如果你想要一个更好的名字,我认为你需要使用DEF文件,来自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文件传递给链接器。

答案 2 :(得分:0)

而不是MessageBox,您可以尝试printf吗? MessageBox是模态的,可能会搞砸了。

答案 3 :(得分:0)

在DLL代码中,使用DLL_PROCESS_DETACH时:

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

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

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

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