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

发布于 2024-11-09 17:10:45 字数 1795 浏览 4 评论 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_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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

萌吟 2024-11-16 17:10:45
  1. DLL_THREAD_ATTACH 替换为 DLL_PROCESS_DETACH
  2. 确保您的函数完全导出为“HookProc”。
  3. 如果没有使用.def 文件来定义函数的导出名称。
  1. Replace DLL_THREAD_ATTACH by DLL_PROCESS_DETACH
  2. Make sure that your function is exported exactly as "HookProc".
  3. If no use .def file to define export name of the function.
风筝有风,海豚有海 2024-11-16 17:10:45

有两件事:

  1. 不要认为 DLL_THREAD_ATTACH 意味着出现问题。当某些东西链接到您的 DLL 正如c-smile所说
  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") 应该可以工作。

如果您想要一个更好的名称,我认为您需要使用 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 文件传递​​给链接器 选项。

Two things:

  1. Don't assume that DLL_THREAD_ATTACH means things are going wrong. It's something that should happen when something links to your DLL as c-smile said.
  2. Since this is a C++ compilation unit, your export will have the mangled name ?HookProc@@YGJHIJ@Z - that's why GetProcAddress(hInstDLL, "HookProc") fails - it's not the right name.

    Use

    extern "C"  __declspec(dllexport) LRESULT CALLBACK HookProc(int nCode, WPARAM wParam, LPARAM lParam);
    

    And you'll get a more manageable name of _HookProc@12, so GetProcAddress(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:

dllexport of a C++ function will expose the function with C++ name mangling. If C++ name mangling is not desired, either use a .def file (EXPORTS keyword) or declare the function as extern "C".

A .def file like the following should do the trick (note: the EXPORTS keyword seems to be case sensitive):

EXPORTS
    HookProc=_HookProc@12

Pass the .def file to the linker using the /def:whatever.def option.

笔落惊风雨 2024-11-16 17:10:45

您可以尝试使用 printf 代替 MessageBox 吗? MessageBox 是模态的,它可能会把事情搞砸。

Instead of MessageBox, can you try printf? MessageBox is modal and it is probably messing things up.

情深缘浅 2024-11-16 17:10:45

在 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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文