如果将句柄创建为函数参数,它将在函数结束时自行关闭吗?
例如:
int readMem(HANDLE processHandle, int address)
{
int memValue = 0;
bool success = ReadProcessMemory(processHandle, (LPVOID)address, &memValue, sizeToReadBytes, NULL);
if (!success)
std::wcout << "Memory read failed on address: " << std::hex << address << "\n";
return memValue;
}
我是否需要在return语句之前显式关闭它,或者最好只在可能的情况下将它们作为引用传递?
或者我只是误解了所有的句柄?我对winapi很新。
答案 0 :(得分:3)
HANDLE
只是typedef
到void *
。
Microsoft明确指出,当您完成句柄后,请务必使用CloseHandle
关闭它。
您的readMem
函数没有创建句柄,因此在那里关闭它是没有意义的。
答案 1 :(得分:1)
您必须明确关闭句柄。
当资源未被明确或隐含地使用且不再需要时,应该关闭句柄。不需要尽快关闭手柄。由您决定何时关闭句柄。例如,要保持文件锁定,您必须保持其句柄处于打开状态。
如果忘记关闭句柄,则会导致资源泄漏。要确保句柄始终关闭,请使用RAII方法:创建接受HANDLE
作为参数的类,不再允许更改句柄并在析构函数中调用CloseHandle
。获取此句柄后立即使用此类包装句柄并保留RAII包装器实例,直到您不需要它为止。
如果您使用RAII并希望在一个例程中获取句柄并在另一个例程中关闭,则需要应用所有权概念。您可以借助智能指针unique_ptr
或shared_ptr
将关闭句柄的责任从一个例程转移到另一个例程。同样,这是安全的方法:智能指针自动释放资源。
答案 2 :(得分:0)
HANDLE
只是一个指针。如果您调用API函数来获取某些句柄值,则需要在丢失句柄之前正确释放它。同样,如果您复制HANDLE
,则不需要执行任何操作,因为它们只是指向资源的指针。
想象HANDLE
为void*
(可能是实际类型)。如果您必须对void*
执行某些操作,则应该对句柄执行此操作。