如何获得与C ++访问WriteableBitmap.PixelBuffer像素?(How to g

2019-08-03 13:00发布

有对C#有很多的样品,但只有一些代码段用于C ++ MSDN上。 我已经把它在一起,我认为它会工作,但我不知道如果我释放所有的COM引用我不得不这样做。

Answer 1:

您的代码是正确的-在引用计数IBufferByteAccess的接口*buffer由调用递增QueryInterface ,你必须调用Release一次,以释放参考。

但是,如果使用ComPtr<T>这变得简单多了-与ComPtr<T>你不能调用任何的三名成员IUnknownAddRefRelease ,以及QueryInterface ); 它阻止你打电话给他们。 相反,它封装了的方式,使得它很难搞砸这些成员函数调用。 下面是如何做到这一点看一个例子:

// Get the buffer from the WriteableBitmap:
IBuffer^ buffer = bitmap->PixelBuffer;

// Convert from C++/CX to the ABI IInspectable*:
ComPtr<IInspectable> bufferInspectable(AsInspectable(buffer));

// Get the IBufferByteAccess interface:
ComPtr<IBufferByteAccess> bufferBytes;
ThrowIfFailed(bufferInspectable.As(&bufferBytes));

// Use it:
byte* pixels(nullptr);
ThrowIfFailed(bufferBytes->Buffer(&pixels));

到呼叫bufferInspectable.As(&bufferBytes)执行安全QueryInterface :它从类型计算IID bufferBytes ,执行QueryInterface ,并附加所得到的指针bufferBytes 。 当bufferBytes超出范围时,它会自动调用Release 。 该代码具有相同的效果是你的,但不容易出错的明确的资源管理。

本例使用以下两种实用程序,这有助于保持代码的清洁:

auto AsInspectable(Object^ const object) -> Microsoft::WRL::ComPtr<IInspectable>
{
    return reinterpret_cast<IInspectable*>(object);
}

auto ThrowIfFailed(HRESULT const hr) -> void
{
    if (FAILED(hr))
        throw Platform::Exception::CreateException(hr);
}

细心的读者会发现,因为这个代码使用ComPtrIInspectable*我们从得到buffer ,这段代码实际上执行额外AddRef / Release比原代码。 我认为,这种影响性能的可能性很小,而且最好从代码,很容易验证是正确的,那么一旦热点被理解优化性能开始。



Answer 2:

这是我试过到目前为止:

// Get the buffer from the WriteableBitmap
IBuffer^ buffer = bitmap->PixelBuffer;

// Get access to the base COM interface of the buffer (IUnknown)
IUnknown* pUnk = reinterpret_cast<IUnknown*>(buffer);

// Use IUnknown to get the IBufferByteAccess interface of the buffer to get access to the bytes
// This requires #include <Robuffer.h>
IBufferByteAccess* pBufferByteAccess = nullptr;
HRESULT hr = pUnk->QueryInterface(IID_PPV_ARGS(&pBufferByteAccess));

if (FAILED(hr))
{
    throw Platform::Exception::CreateException(hr);
}

// Get the pointer to the bytes of the buffer
byte *pixels = nullptr;
pBufferByteAccess->Buffer(&pixels);

// *** Do the work on the bytes here ***

// Release reference to IBufferByteAccess created by QueryInterface.
// Perhaps this might be done before doing more work with the pixels buffer,
// but it's possible that without it - the buffer might get released or moved
// by the time you are done using it.
pBufferByteAccess->Release();


文章来源: How to get access to WriteableBitmap.PixelBuffer pixels with C++?