【发布时间】:2018-08-01 00:17:27
【问题描述】:
关于GlobalLock 的文档说:
返回值
如果函数成功,返回值是指向内存块第一个字节的指针。
如果函数失败,返回值为NULL。要获取扩展错误信息,请调用 GetLastError。备注
进程为对象对 GlobalLock 进行的每个成功调用都必须与对 GlobalUnlock 的相应调用相匹配。
....
如果指定的内存块已被丢弃或内存块的大小为零,则此函数返回 NULL。
因此,正如我们所见,如果错误或内存块大小为零字节大小,GlobalLock() 可能会返回 NULL。
另一方面,只有当GlobalLock() 成功时才应该调用GlobalUnlock()。那么,如何正确定义应该调用 GlobalUnlock() 的情况?从以下变体中哪种方法是正确的?为什么?
变体 0:
HGLOBAL hMem = /*some handle on global memory block*/;
// lock block
auto pMem = static_cast<LPBYTE>(::GlobalLock(hMem));
if (pMem!=nullptr)
{
// ... work with pMem
}
// call unlock in any case
::GlobalUnlock(hMem);
变体 1:
HGLOBAL hMem = /*some handle on global memory block*/;
// lock block
auto pMem = static_cast<LPBYTE>(::GlobalLock(hMem));
if (pMem!=nullptr)
{
// ... work with pMem
// unlock block
::GlobalUnlock(hMem);
}
变体 2:
HGLOBAL hMem = /*some handle on global memory block*/;
// lock block
auto pMem = static_cast<LPBYTE>(::GlobalLock(hMem));
auto isMemLocked = (pMem!=nullptr);
if (isMemLocked)
{
// ... work with pMem
}
else
{
// is it real error?
isMemLocked = ::GetLastError()==NOERROR;
}
if (isMemLocked)
{
// unlock block
::GlobalUnlock(hMem);
}
更新: 我们假设 hMem 是有效的(句柄不为 NULL)。
P.S.:非常感谢您的回答。
【问题讨论】:
-
@RbMm,谢谢,但为什么不是变体 2?为什么你认为零大小块的 NULL 也不是成功调用?
-
我强烈建议为此使用 RAII 包装器。
global_locker接受HGLOBAL
标签: winapi visual-c++