如何使用C++;? C++中有很多样本,但在MSDN上只有一些C++代码片段。我已经把它放在一起,我认为它会起作用,但我不确定我是否发布了所有必须发布的COM引用。

如何使用C++;? C++中有很多样本,但在MSDN上只有一些C++代码片段。我已经把它放在一起,我认为它会起作用,但我不确定我是否发布了所有必须发布的COM引用。,com,windows-runtime,winrt-xaml,c++-cx,Com,Windows Runtime,Winrt Xaml,C++ Cx,这是我迄今为止尝试的: // 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

这是我迄今为止尝试的:

// 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();
//从WriteableBitmap获取缓冲区
IBuffer^buffer=位图->像素缓冲区;
//访问缓冲区的基本COM接口(IUnknown)
IUnknown*朋克=重新解释投射(缓冲区);
//使用IUnknown获取缓冲区的IBufferByteAccess接口以访问字节
//这需要#包括
IBufferByteAccess*pBufferByteAccess=nullptr;
HRESULT hr=pUnk->QueryInterface(IID_PPV_ARGS(&pBufferByteAccess));
如果(失败(小时))
{
抛出平台::异常::CreateException(hr);
}
//获取指向缓冲区字节的指针
字节*像素=空PTR;
pBufferByteAccess->Buffer(&pixels);
//***在此处对字节进行处理***
//发布对QueryInterface创建的IBufferByteAccess的引用。
//也许这可以在对像素缓冲区做更多工作之前完成,
//但如果没有它,缓冲区可能会被释放或移动
//当你用完它的时候。
pBufferByteAccess->Release();
您的代码是正确的——
*buffer
IBufferByteAccess
接口上的引用计数随着对
QueryInterface
的调用而增加,您必须调用
Release
一次才能释放该引用

但是,如果您使用
ComPtr
,这会变得简单得多——使用
ComPtr
,您不能调用
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));

细心的读者会注意到,由于此代码使用
ComPtr
作为我们从
缓冲区获得的
IInspectable*
,因此与原始代码相比,此代码实际上执行了额外的
AddRef
/
释放。我认为这种影响性能的可能性很小,最好从易于验证为正确的代码开始,然后在了解热点后针对性能进行优化。

使用(而不是C++/CX)时,有一种更方便(也更危险)的替代方法。语言投影在
IBuffer
接口上生成一个
data()
helper函数,该函数将
uint8\u t*
返回内存缓冲区

假设
bitmap
是一种类型,则可以将代码缩减为:

uint8_t*像素{bitmap.PixelBuffer().data()};
//***在此处对字节进行处理***
//无需清理;它已经在data()的实现中处理过了
在代码
中,像素
是指向由
位图
实例控制的数据的原始指针。因此,它只在
位图
处于活动状态时有效,但代码中没有任何内容可以帮助编译器(或读取器)跟踪该依赖关系


作为参考,在
WriteableBitmap::PixelBuffer
文档中有一个说明使用(否则未记录)辅助函数
data()

的示例,您应该使用
ComPtr
<代码>ComPtr
超出范围时将自动调用
Release
。否则,这看起来是正确的。使用
IBufferByteAccess
是Marian Luparu在今年的//Build/talk中演示的示例之一:。
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);
}