有对C#有很多的样品,但只有一些代码段用于C ++ MSDN上。 我已经把它在一起,我认为它会工作,但我不知道如果我释放所有的COM引用我不得不这样做。
Answer 1:
您的代码是正确的-在引用计数IBufferByteAccess
的接口*buffer
由调用递增QueryInterface
,你必须调用Release
一次,以释放参考。
但是,如果使用ComPtr<T>
这变得简单多了-与ComPtr<T>
你不能调用任何的三名成员IUnknown
( AddRef
, Release
,以及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);
}
细心的读者会发现,因为这个代码使用ComPtr
为IInspectable*
我们从得到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++?