Getting an array of bytes out of Windows::Storage::Streams::IBuffer

13,724

Solution 1

You can use IBufferByteAccess, through exotic COM casts:

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;

}

Code sample copied from http://cm-bloggers.blogspot.fi/2012/09/accessing-image-pixel-data-in-ccx.html

Solution 2

Also check this method:

IBuffer -> Platform::Array
CryptographicBuffer.CopyToByteArray

Platform::Array -> IBuffer
CryptographicBuffer.CreateFromByteArray

As a side note, if you want to create Platform::Array from simple C++ array you could use Platform::ArrayReference, for example:

char* c = "sdsd";
Platform::ArrayReference<unsigned char> arraywrapper((unsigned char*) c, sizeof(c));

Solution 3

This is a C++/CX version:

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;
}

For more information see Array and WriteOnlyArray (C++/CX).

Solution 4

As mentioned before, WindowsRuntimeBufferExtensions from the namespace System::Runtime::InteropServices::WindowsRuntime is only available for .Net applications and not for native C++ applications.

A possible solution would be to use 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];

    (...)
}

Solution 5

This should work with WinRT extensions:

// 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
Share:
13,724
Alam Brito
Author by

Alam Brito

Updated on June 12, 2022

Comments

  • Alam Brito
    Alam Brito almost 2 years

    I have an object that implements the interface Windows::Storage::Streams::IBuffer, and I want to get an array of bytes out of it, however while looking at the documentation this interface looks pretty useless, and the documentation does not offer any reference to any other class that could be combined with this interface to achieve my purpose. All I have found so far with google is a reference to the .Net class WindowsRuntimeBufferExtensions but I am using C++ so this is also a dead end.

    Can someone give a hint on how to get an array of bytes from Windows::Storage::Streams::IBuffer in C++?

  • MSN
    MSN almost 12 years
    @user787913, I was confused at first as well.
  • yms
    yms almost 12 years
    @MSN WindowsRuntimeBufferExtensions is a class in .Net framework, it cannot be used from a native C++ application
  • Alam Brito
    Alam Brito over 11 years
    I changed my implementation and I am using this approach now since it improves the performance of my app. Thanks.
  • Wayne Uroda
    Wayne Uroda about 9 years
    Thanks this saved me a headache!, for reference, ArrayReference is in the Platform namespace.
  • Robin R
    Robin R about 9 years
    WARNING: sizeof(c) will produce the size of the pointer, not the length of the string.
  • Alam Brito
    Alam Brito about 9 years
    There is almost no documentation about this class Platform::ArrayReference, where did you find this information if I may ask?
  • Robin R
    Robin R about 9 years
    Here's an example from MSDN msdn.microsoft.com/en-us/library/hh700131.aspx "Use ArrayReference to avoid copying data"