在句柄上调用CloseHandle是一个函数参数?

时间:2016-03-05 18:12:37

标签: c++ winapi

如果将句柄创建为函数参数,它将在函数结束时自行关闭吗?

例如:

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很新。

3 个答案:

答案 0 :(得分:3)

HANDLE只是typedefvoid *

Microsoft明确指出,当您完成句柄后,请务必使用CloseHandle关闭它。

您的readMem函数没有创建句柄,因此在那里关闭它是没有意义的。

答案 1 :(得分:1)

您必须明确关闭句柄。

当资源未被明确或隐含地使用且不再需要时,应该关闭句柄。不需要尽快关闭手柄。由您决定何时关闭句柄。例如,要保持文件锁定,您必须保持其句柄处于打开状态。

如果忘记关闭句柄,则会导致资源泄漏。要确保句柄始终关闭,请使用RAII方法:创建接受HANDLE作为参数的类,不再允许更改句柄并在析构函数中调用CloseHandle。获取此句柄后立即使用此类包装句柄并保留RAII包装器实例,直到您不需要它为止。

如果您使用RAII并希望在一个例程中获取句柄并在另一个例程中关闭,则需要应用所有权概念。您可以借助智能指针unique_ptrshared_ptr将关闭句柄的责任从一个例程转移到另一个例程。同样,这是安全的方法:智能指针自动释放资源。

答案 2 :(得分:0)

HANDLE只是一个指针。如果您调用API函数来获取某些句柄值,则需要在丢失句柄之前正确释放它。同样,如果您复制HANDLE,则不需要执行任何操作,因为它们只是指向资源的指针。

想象HANDLEvoid*(可能是实际类型)。如果您必须对void*执行某些操作,则应该对句柄执行此操作。