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’sCComPtr
, although
some operations thatCComPtr
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 newComPtr
, 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
How to Brace-Initialize an Std::Array of Std::Pairs
Int *Array = New Int[N]; What Is This Function Actually Doing
What Are Use Cases for Structured Bindings
Static Polymorphism Definition and Implementation
How to Rotate a N X N Matrix by 90 Degrees
C++ Read File Line by Line Then Split Each Line Using the Delimiter
Stepping into Qt Sources in Qt Creator (In Ubuntu Linux)
What Is Better: Reserve Vector Capacity, Preallocate to Size or Push Back in Loop
How to Produce Deterministic Binary Output with G++
Validate Authenticode Signature on Exe - C++ Without Capicom
How to Call Memcpy() and Memmove() with "Number of Bytes" Set to Zero
In C++ Main Function Is the Entry Point to Program How to Change It to an Other Function
Debug Assertion Failed! Expression: _Acrt_First_Block == Header
How to Parallelize a for Loop Through a C++ Std::List Using Openmp