提问人:Vk0726 提问时间:11/9/2023 最后编辑:Remy LebeauVk0726 更新时间:11/9/2023 访问量:40
调用 ::GetModuleHandleEx unique_ptr具有自定义删除程序以自动处理释放资源
Calling ::GetModuleHandleEx with unique_ptr having custom deleter to handle freeing resources automatically
问:
我需要在下面的代码中释放吗?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
如果答案是肯定的,那么我想尝试像我们在这里这样的东西:
将 std::unique_ptr 用于 Windows 句柄
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()
答:
首先,您的使用是错误的,因为您没有传递您正在寻找的模块内部的内存地址。如果要按名称查找模块,请不要使用 .在这种情况下,您不妨直接使用,完全不用担心。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
函数递减引用计数。
所以是的,如果你不使用 ,你需要打电话,例如:FreeLibrary()
GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT
HMODULE hm = NULL;
::GetModuleHandleExW(0, L"Test.dll", &hm);
...
FreeLibrary(hm);
如果你想使用自定义来调用,这当然是可行的,但是你无法获取它所持有的指针的地址,所以你必须在你从中构造之前检索 ,例如:unique_ptr
Deleter
FreeLibrary()
unique_ptr
HMODULE
unique_ptr
HMODULE hm = NULL;
::GetModuleHandleExW(0, L"Test.dll", &hm);
unique_module um {hm};
否则,您可以简单地忘记 ,如果必须使用 ,则直接使用 ,或者只是改用。Deleter
GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT
GetModuleHandleExW()
GetModuleHandleW()
评论