如何正确从 SoftwareBitmap (UWP) 中释放 BitmapBuffer?

Paw*_*wel 5 windows c++-cx windows-10-iot-core uwp windows-10-universal

我很难在 UWP 上的 C++/CX 代码中正确释放BitmapBuffer锁定的方法。SoftwareBitmap.LockBuffer()

基本代码如下所示(这是来自 Microsoft 的 OpenCV 桥示例,可在此处获取)。

bool OpenCVHelper::GetPointerToPixelData(SoftwareBitmap^ bitmap, unsigned char** pPixelData, unsigned int* capacity)
{
   BitmapBuffer^ bmpBuffer = bitmap->LockBuffer(BitmapBufferAccessMode::ReadWrite);
   IMemoryBufferReference^ reference = bmpBuffer->CreateReference();

   ComPtr<IMemoryBufferByteAccess> pBufferByteAccess;
   if ((reinterpret_cast<IInspectable*>(reference)->QueryInterface(IID_PPV_ARGS(&pBufferByteAccess))) != S_OK)
   {
    return false;
   }

   if (pBufferByteAccess->GetBuffer(pPixelData, capacity) != S_OK)
   {
    return false;
   }
   return true;
}
Run Code Online (Sandbox Code Playgroud)

然后该缓冲区 ( pPixelData) 用于初始化cv:Mat对象(浅拷贝)。并且永远不会被释放。

连续调用LockBuffer()同一SoftwareBitmap对象会引发异常:

Platform::AccessDeniedException ^ 位于内存位置 0x00000002CEEFDCC0。HRESULT:0x80070005 访问被拒绝。WinRT 信息:已获取位图共享锁

如何正确释放这个缓冲区?特别是在 C++/CX 中?

我尝试保留引用,以便在不再需要时释放它。在 C++/CX 中,Dispose() 或 Close() 方法无法访问,编译器建议改为调用析构函数:

BitmapBuffer^ bmpBuffer = nullptr;
// ... get the buffer, use it
//((IDisposable^)bmpBuffer)->Dispose();
bmpBuffer->~BitmapBuffer();
Run Code Online (Sandbox Code Playgroud)

但它不起作用(什么也不做)。正在调用析构函数,但对 LockBuffer() 的另一次调用会引发与之前相同的错误。

Sun*_* Wu 0

如何正确从 SoftwareBitmap (UWP) 中释放 BitmapBuffer?

在完成他们的工作之后BitmapBufferIMemoryBufferReference这些对象可以通过调用表达式来关闭delete。更多细节请查看析构函数。例如:

SoftwareBitmap^ bitmap = ref new SoftwareBitmap(
    BitmapPixelFormat::Bgra8,
    100,
    200,
    BitmapAlphaMode::Premultiplied);
BitmapBuffer^ bmpBuffer = bitmap->LockBuffer(BitmapBufferAccessMode::ReadWrite); 
IMemoryBufferReference^ reference = bmpBuffer->CreateReference();
delete reference;
delete bmpBuffer; 
BitmapBuffer^ bmpBuffer2 = bitmap->LockBuffer(BitmapBufferAccessMode::ReadWrite);
Run Code Online (Sandbox Code Playgroud)

如上面的代码片段所示,删除BitmapBuffer对象后,您可以成功再次锁定缓冲区。