Getting an Array of Bytes Out of Windows::Storage::Streams::Ibuffer

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

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

how to copy bytes into a Windows::Storage::Streams::Buffer or IBuffer for ouput via Windows::Storage::Streams::DataWriter::WriteBuffer()

It appears that the same function that can be used to obtain a pointer to the Buffer memory area to copy data from the Buffer into a native memory area can also be used to obtain a pointer that can be used to copy data into the Buffer. See Obtaining pointers to data buffers (C++/CX). and see as well COM Coding Practices for information about the IID_PPV_ARGS() macro and the ATL smart pointer class CComPtr. See QueryInterface: Navigating in an Object as well.

ComPtr is the WRL version of the ATL CComPtr (see Native WinRT Inheritance as well as Windows Runtime C++ Template Library (WRL) which has links to a variety of supporting topics for WRL and WinRT).

(ComPtr is a WRL smart pointer. It automates some aspects of COM that
otherwise get tedious fast. It’s similar to ATL’s CComPtr, although
some operations that CComPtr performed implicitly now require explicit
code, largely because those implicit operations were responsible for a
lot of bugs in code written by people who didn’t really understand how
CComPtr works. With the new ComPtr, a failure to understand how it
works is more likely to lead to a compiler error than a runtime bug.)

as well as ComPtr in the DirectXTK wiki

Microsoft::WRL::ComPtr is a C++ template smart-pointer for COM objects
that is used extensively in Windows Runtime (WinRT) C++ programming.
It works in Win32 desktop applications as well. It is similar to ATL's
CComPtr with some useful improvements. Microsoft::WRL:::ComPtr is in
the Windows 8.x SDK and Windows 10 SDK, which, unlike ATL, is
available when using the Express versions of Visual Studio. It is used
extensively in DirectX Tool Kit to properly handle COM reference
counting maintenance.

#include <robuffer.h>  

byte* GetPointerToPixelData(IBuffer^ pixelBuffer, unsigned int *length)
{
if (length != nullptr)
{
*length = pixelBuffer->Length;
}
// Query the IBufferByteAccess interface.
Microsoft::WRL::ComPtr<IBufferByteAccess> bufferByteAccess;
reinterpret_cast<IInspectable*>(pixelBuffer)->QueryInterface(IID_PPV_ARGS(&bufferByteAccess));

// Retrieve the buffer data.
byte* pixels = nullptr;
bufferByteAccess->Buffer(&pixels);
return pixels;
}

Warning: You must ensure that you do not exceed the capacity of the memory allocated to the Buffer (you can check the Capacity attribute of the buffer). After copying from a native variable into the Buffer you must also set the Length attribute to the actual number of bytes of data set into the Buffer.

For example:

// test structs for binary data to parse.
struct struct1 {
unsigned char uchMajorClass;
unsigned char uchMinorClass;
long lVal1;
};

void testfunc (IOutputStream^ outputStream)
{
auto dataWriter = ref new DataWriter(outputStream);

struct1 myStruct1 = { 1, 11,0 };

Buffer ^myBuffer = ref new Buffer(sizeof(struct1)); // allocate Buffer of desired size

unsigned int len;
struct1 *sp = (struct1 *)GetPointerToPixelData(myBuffer, &len); // get native pointer

// we could use myBuffer->Capacity at this point to check the capacity or
// max size in bytes of the buffer.
*sp = myStruct1; // copy data from native into the Buffer
myBuffer->Length = sizeof(*sp); // set the data length
dataWriter->WriteBuffer(myBuffer);

}

How can I get Windows.Storage.Streams.IInputStream inputStream length?

Hi Nico sorry for the late update. I tried everything but TCP is nearly impossible for HoloLens with UWP app. So I tried UDP and it works perfectly (https://github.com/mbaytas/HoloLensUDP). I hope Microsoft put a TCP example for HoloLens 1 and 2 in near future.

How to read all bytes of a file in winrt with ReadBufferAsync?

    #include <wrl.h>
#include <robuffer.h>
uint8_t* GetBufferData(winrt::Windows::Storage::Streams::IBuffer& buffer)
{
::IUnknown* unknown = winrt::get_unknown(buffer);
::Microsoft::WRL::ComPtr<::Windows::Storage::Streams::IBufferByteAccess> bufferByteAccess;
HRESULT hr = unknown->QueryInterface(_uuidof(::Windows::Storage::Streams::IBufferByteAccess), &bufferByteAccess);
if (FAILED(hr))
return nullptr;
byte* bytes = nullptr;
bufferByteAccess->Buffer(&bytes);
return bytes;
}

https://learn.microsoft.com/en-us/cpp/cppcx/obtaining-pointers-to-data-buffers-c-cx?view=vs-2017

https://learn.microsoft.com/en-us/windows/uwp/xbox-live/storage-platform/connected-storage/connected-storage-using-buffers

Converting IBuffer to Buffer array

You can use a DataReader, for instance:

    Windows.Storage.StorageFile.getFileFromApplicationUriAsync(new Windows.Foundation.Uri("ms-appx:///Assets/textfile.txt")).then(
function (myFile) {
Windows.Storage.FileIO.readBufferAsync(myFile).done(
function (buffer) {
var myArray = new Uint8Array(buffer.length);

var dataReader = Windows.Storage.Streams.DataReader.fromBuffer(buffer);
dataReader.readBytes(myArray)
dataReader.close();
}
);
}
);

Converting between WinRT HttpBufferContent and unmanaged memory in C++cx

I think you are making at least one unnecessary copy of your data in your current approach for HttpBufferContent to std::string, you could improve this by accessing the IBuffer data directly, see the accepted answer here: Getting an array of bytes out of Windows::Storage::Streams::IBuffer

C++ CX - Convert Windows::Storage::Streams::Buffer to Platform::String

The documentation shows that CrytographicBuffer is one of the more useful concrete types that can be used for stream I/O, and it has functions for conversion to/from strings.

Examples here on MSDN



Related Topics



Leave a reply



Submit