如何将字节复制到 Windows::Storage::Streams::Buffer 或通过 Windows::Storage::Streams::DataWriter::WriteBuffer() 缓冲输出
how to copy bytes into a Windows::Storage::Streams::Buffer or IBuffer for ouput via Windows::Storage::Streams::DataWriter::WriteBuffer()
我正在使用一个示例 UWP C++/CX 程序创建两个 UDP 网络通信线程,它们使用 Windows::Storage::Streams::DataWriter
和 Windows::Storage::Streams::DataReader
相互发送数据,同时更新显示的 window 显示来回的数据。
使用 Platform::String
变量和 DataWriter->WriteString()
的初始实现工作正常。但是现在我想实现一个二进制协议,它具有包含各种类型信息的可变长度缓冲区。
DataReader->ReadBuffer()
和 DataWriter->WriteBuffer()
需要 Windows::Storage::Streams::Buffer
.
要访问 ReadBuffer()
返回的缓冲区,我正在使用一个函数,如果可以在 Obtaining pointers to data buffers (C++/CX) which is similar to an answer in Getting an array of bytes out of Windows::Storage::Streams::IBuffer
的网络上找到该函数的源代码
#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;
}
但是我一直无法找到如何将本机结构复制到缓冲区中,以便可以使用 DataWriter->WriteBuffer()
将其发送出去。
如果我有一些二进制数据结构,我如何将这个结构的内容复制到输出 Windows::Storage::Streams::Buffer
以便与 DataWriter->WriteBuffer()
一起使用?
看来,可用于获取指向 Buffer
内存区域的指针以将数据从 Buffer
复制到本机内存区域的同一函数也可用于获取可用于将数据复制到 Buffer
中的指针。另见 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。
ComPtr
是 ATL CComPtr
的 WRL 版本(请参阅 Native WinRT Inheritance as well as Windows Runtime C++ Template Library (WRL),其中包含指向 WRL 和 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.)
以及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;
}
警告:您必须确保不超过分配给Buffer
的内存容量(您可以检查Capacity
属性缓冲区)。从本机变量复制到 Buffer
后,您还必须将 Length
属性设置为 Buffer
.
中数据集的实际字节数
例如:
// 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);
}
我正在使用一个示例 UWP C++/CX 程序创建两个 UDP 网络通信线程,它们使用 Windows::Storage::Streams::DataWriter
和 Windows::Storage::Streams::DataReader
相互发送数据,同时更新显示的 window 显示来回的数据。
使用 Platform::String
变量和 DataWriter->WriteString()
的初始实现工作正常。但是现在我想实现一个二进制协议,它具有包含各种类型信息的可变长度缓冲区。
DataReader->ReadBuffer()
和 DataWriter->WriteBuffer()
需要 Windows::Storage::Streams::Buffer
.
要访问 ReadBuffer()
返回的缓冲区,我正在使用一个函数,如果可以在 Obtaining pointers to data buffers (C++/CX) which is similar to an answer in Getting an array of bytes out of Windows::Storage::Streams::IBuffer
#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;
}
但是我一直无法找到如何将本机结构复制到缓冲区中,以便可以使用 DataWriter->WriteBuffer()
将其发送出去。
如果我有一些二进制数据结构,我如何将这个结构的内容复制到输出 Windows::Storage::Streams::Buffer
以便与 DataWriter->WriteBuffer()
一起使用?
看来,可用于获取指向 Buffer
内存区域的指针以将数据从 Buffer
复制到本机内存区域的同一函数也可用于获取可用于将数据复制到 Buffer
中的指针。另见 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。
ComPtr
是 ATL CComPtr
的 WRL 版本(请参阅 Native WinRT Inheritance as well as Windows Runtime C++ Template Library (WRL),其中包含指向 WRL 和 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 howCComPtr
works. With the newComPtr
, a failure to understand how it works is more likely to lead to a compiler error than a runtime bug.)
以及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'sCComPtr
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;
}
警告:您必须确保不超过分配给Buffer
的内存容量(您可以检查Capacity
属性缓冲区)。从本机变量复制到 Buffer
后,您还必须将 Length
属性设置为 Buffer
.
例如:
// 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);
}