15

我有一个实现接口的对象,Windows::Storage::Streams::IBuffer我想从中获取一个字节数组,但是在查看文档时,这个接口看起来非常无用,并且文档没有提供对任何其他可以组合的类的任何引用用这个接口来达到我的目的。到目前为止,我在谷歌上发现的只是对 .Net 类WindowsRuntimeBufferExtensions的引用,但我使用的是 C++,所以这也是一个死胡同。

Windows::Storage::Streams::IBuffer有人可以提示如何从C++中获取字节数组吗?

4

7 回答 7

12

您可以通过奇异的 COM 强制转换使用 IBufferByteAccess:

byte* GetPointerToPixelData(IBuffer^ buffer)
{
   // Cast to Object^, then to its underlying IInspectable interface.

   Object^ obj = buffer;
   ComPtr<IInspectable> insp(reinterpret_cast<IInspectable*>(obj));

   // Query the IBufferByteAccess interface.
   ComPtr<IBufferByteAccess> bufferByteAccess;
   ThrowIfFailed(insp.As(&bufferByteAccess));

   // Retrieve the buffer data.

   byte* pixels = nullptr;
   ThrowIfFailed(bufferByteAccess->Buffer(&pixels));

   return pixels;

}

从http://cm-bloggers.blogspot.fi/2012/09/accessing-image-pixel-data-in-ccx.html复制的代码示例

于 2013-01-05T14:12:32.613 回答
9

还要检查这个方法:

IBuffer -> Platform::Array
CryptographicBuffer.CopyToByteArray

Platform::Array -> IBuffer
CryptographicBuffer.CreateFromByteArray

作为旁注,如果您想Platform::Array从简单的 C++ 数组创建,您可以使用Platform::ArrayReference,例如:

char* c = "sdsd";
Platform::ArrayReference<unsigned char> arraywrapper((unsigned char*) c, sizeof(c));
于 2013-05-20T08:57:00.507 回答
9

这是 C++/CX 版本:

std::vector<unsigned char> getData( ::Windows::Storage::Streams::IBuffer^ buf )
{
    auto reader = ::Windows::Storage::Streams::DataReader::FromBuffer(buf);

    std::vector<unsigned char> data(reader->UnconsumedBufferLength);

    if ( !data.empty() )
        reader->ReadBytes(
            ::Platform::ArrayReference<unsigned char>(
                &data[0], data.size()));

    return data;
}

有关详细信息,请参阅数组和 WriteOnlyArray (C++/CX)

于 2013-01-17T16:39:44.630 回答
5

如前所述,WindowsRuntimeBufferExtensions命名空间System::Runtime::InteropServices::WindowsRuntime仅适用于 .Net 应用程序,不适用于本机 C++ 应用程序。

一个可能的解决方案是使用Windows::Storage::Streams::DataReader

void process(Windows::Storage::Streams::IBuffer^ uselessBuffer)
{
    Windows::Storage::Streams::DataReader^ uselessReader =
             Windows::Storage::Streams::DataReader::FromBuffer(uselessBuffer);
    Platform::Array<Byte>^ managedBytes = 
                         ref new Platform::Array<Byte>(uselessBuffer->Length);
    uselessReader->ReadBytes( managedBytes );                               
    BYTE * bytes = new BYTE[uselessBuffer->Length];
    for(int i = 0; i < uselessBuffer->Length; i++)
        bytes[i] = managedBytes[i];

    (...)
}
于 2012-08-13T20:12:53.287 回答
3

这应该适用于 WinRT 扩展:

// Windows::Storage::Streams::DataReader
// buffer is assumed to be of type Windows::Storage::Streams::IBuffer
// BYTE = unsigned char

DataReader^ reader = DataReader::FromBuffer(buffer);

BYTE *extracted = new BYTE[buffer->Length];

// NOTE: This will read directly into the allocated "extracted" buffer
reader->ReadBytes(Platform::ArrayReference<BYTE>(extracted, buffer->Length));

// ... do something with extracted...

delete [] extracted; // don't forget to free the space
于 2015-03-13T13:45:02.017 回答
2

由于这个问题被标记为,这里有一个使用C++/WinRT的解决方案。它本质上与引擎盖下的这个答案相同,但更易于访问。投影上的(未记录的)data()助手完成了IBuffer所有繁重的工作:

uint8_t* GetPointerToPixelData(::winrt::Windows::Storage::Streams::IBuffer const& buffer)
{
    return buffer.data();
}

不幸的是(还没有)官方文档,我只是在该WritableBitmap.PixelBuffer属性的示例代码中偶然发现了这一点(确保从右上角的语言下拉列表中选择“C++/WinRT” )。

从语言下拉列表中选择“C++/CX”IBufferByteAccess时,该文档条目也提供了相同的解决方案(查询接口)。

于 2019-05-03T17:54:38.223 回答
-1

像静态方法一样使用扩展方法

IBuffer *buffer;
array<unsigned char>^ result= System::Runtime::InteropServices::WindowsRuntime::WindowsRuntimeBufferExtensions::ToArray(buffer);
于 2012-08-07T20:55:45.960 回答