我需要释放下面代码中的HMODULE
吗?
DWORD flags =
GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS;
HMODULE hm = 0;
::GetModuleHandleExW(flags, L"Test.dll", &hm);
HRSRC hResource =
::FindResourceW(hm, MAKEINTRESOURCEW(TEST1), L"ICON");
if (hResource) {
HGLOBAL hLoaded = LoadResource(hm, hResource);
if (hLoaded) {
size = (int)SizeofResource(hm, hResource);
auto lpAddress = LockResource(hLoaded);
//Read resource here
UnlockResource(hLoaded);
} else {
//Error logging
}
FreeResource(hLoaded);
} else {
//Error logging
}
字符串
在这里,我在正确的位置释放了大部分资源,除了可能的HMODULE
!我需要释放hm
吗?我的理解是,我们只得到HMODULE
,而不是在这里加载库,所以我们可能不需要释放它?
如果答案是肯定的,那么我想尝试一下我们在这里所做的事情:
Using std::unique_ptr for Windows HANDLEs
struct Deleter {
void operator()(HMODULE hModule) const
{
if (hModule != nullptr)
{
FreeLibrary(hModule);
}
}
};
using unique_module = std::unique_ptr<std::remove_pointer<HMODULE>::type, Deleter>;
型
但是我有点困惑,比如如何使用这个unique_module
。
与此同时,我正在写:
HMODULE hm = 0;
unique_module um {hm};
::GetModuleHandleExW(flags, L"Test.dll", &um.get());
型
虽然我没有编译和测试,但这对我来说似乎是错误的,我需要输入如何正确编写这个自定义删除器并将其与HMODULE
一起使用,以及如何使用::GetModuleHandleEx()
调用它。
1条答案
按热度按时间anhgbhbe1#
首先,你使用
GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS
是错误的,因为你没有给GetModuleHandleExW()
传递一个你正在寻找的模块内部的内存地址。如果你想通过它的名字找到一个模块,那么不要使用GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS
。在这种情况下,你可以直接使用GetModuleHandleW()
,而不用担心FreeLibrary()
。话虽如此
为了回答你的实际问题,
GetModuleHandleExW()
文档说:https://learn.microsoft.com/en-us/windows/win32/api/libloaderapi/nf-libloaderapi-getmodulehandleexw
检索指定模块的模块句柄并递增模块的引用计数,除非指定了
GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT
。模块必须已由调用进程加载。...
[in] dwFlags
个此参数可以是零或以下值中的一个或多个。如果模块的引用计数递增,则调用者必须使用
FreeLibrary
函数在不再需要模块句柄时递减引用计数。所以是的,如果你没有使用
GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT
,你需要调用FreeLibrary()
,例如:字符串
如果你想使用
unique_ptr
和一个自定义的Deleter
来调用FreeLibrary()
,这当然是可行的,但是你不能获得unique_ptr
所持有的指针的地址,所以你必须在从它构造unique_ptr
之前 * 检索HMODULE
,例如:型
否则,您可以简单地忘记
Deleter
,如果必须使用GetModuleHandleExW()
,则使用GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT
,或者仅使用GetModuleHandleW()
。