You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用带自定义删除器的unique_ptr调用GetModuleHandleEx及HMODULE释放问题

HMODULE是否需要释放?

首先明确:是否需要释放HMODULE取决于调用GetModuleHandleExW时使用的标志:

  • 若调用时未指定GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT,系统会自动增加模块的引用计数,此时必须调用FreeLibrary释放HMODULE,否则会造成模块引用计数泄漏,导致模块无法正常卸载。
  • 你的代码中使用了GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS,该标志仅用于通过地址定位模块,不会改变引用计数的默认行为——系统仍会给模块的引用计数+1,因此你必须释放这个HMODULE。

另外补充:你现有代码中的FreeResource调用是冗余的,LoadResource返回的HGLOBAL无需手动释放,系统会在模块卸载时自动清理,强行调用反而可能引发问题。


带自定义删除器的unique_ptr正确用法

你定义的删除器是正确的,但使用方式有误——unique_ptr::get()返回的是内部指针的副本,无法直接取地址传给GetModuleHandleExW(因为get()返回的是右值,且unique_ptr的内部指针不能通过这种方式修改)。以下是两种正确的实现方式:

方法一:临时存储HMODULE后转移给unique_ptr(推荐)

struct Deleter {
    void operator()(HMODULE hModule) const
    {
        if (hModule != nullptr)
        {
            FreeLibrary(hModule);
        }
    }
};

using unique_module = std::unique_ptr<std::remove_pointer<HMODULE>::type, Deleter>;

// 使用示例
DWORD flags = GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS;
HMODULE hm = nullptr;
if (::GetModuleHandleExW(flags, L"Test.dll", &hm))
{
    unique_module um(hm); // 将获取到的HMODULE转移给unique_ptr,后续自动释放
    // 通过um.get()访问HMODULE
    HRSRC hResource = ::FindResourceW(um.get(), MAKEINTRESOURCEW(TEST1), L"ICON");
    // ... 后续资源操作代码
}
else
{
    // 错误处理
}

方法二:直接修改unique_ptr内部指针(可读性较差)

若想让GetModuleHandleExW直接写入unique_ptr的内部指针,可通过&*um获取内部指针的引用地址(前提是unique_ptr初始化为nullptr):

unique_module um(nullptr);
if (::GetModuleHandleExW(flags, L"Test.dll", &*um))
{
    // 通过um.get()操作模块
}

额外优化方案

如果你的场景只是临时获取模块句柄读取资源,不需要保留模块引用,可以在调用GetModuleHandleExW时添加GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT标志,此时系统不会增加模块引用计数,无需调用FreeLibrary释放HMODULE,也就不需要使用带删除器的unique_ptr:

DWORD flags = GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS | GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT;
HMODULE hm = nullptr;
if (::GetModuleHandleExW(flags, L"Test.dll", &hm))
{
    // 使用hm读取资源,无需释放
}

内容的提问来源于stack exchange,提问作者Vk0726

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.06 16:32:40