我正在使用示例UWP C ++ / CX程序创建两个UDP网络通信线程,这些线程使用Windows::Storage::Streams::DataWriter
和Windows::Storage::Streams::DataReader
相互发送数据,同时更新显示数据的显示窗口
使用Platform::String
变量和DataWriter->WriteString()
的初始实现工作正常。但是现在我想实现一个包含各种类型信息的可变长度缓冲区的二进制协议。
DataReader->ReadBuffer()
和DataWriter->WriteBuffer()
需要Windows::Storage::Streams::Buffer
。
要访问ReadBuffer()
返回的缓冲区,我正在使用一个函数,如果在Obtaining pointers to data buffers (C++/CX)网站上找到该函数,则该函数类似于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;
}
但是我一直无法找到如何将本机结构复制到Buffer中,以便可以使用DataWriter->WriteBuffer()
发送它。
如果我有一些二进制数据结构,如何将此结构的内容复制到输出Windows::Storage::Streams::Buffer
以与DataWriter->WriteBuffer()
一起使用?
答案 0 :(得分:0)
似乎可以使用相同的函数来获取指向Buffer
内存区域的指针,以将数据从Buffer
复制到本机内存区域,也可用于获取指针可用于将数据复制到Buffer
。有关IID_PPV_ARGS()
宏和ATL智能指针类CComPtr
的信息,请参阅Obtaining pointers to data buffers (C++/CX).并查看COM Coding Practices。另见QueryInterface: Navigating in an Object。
ComPtr
是ATL CComPtr
的WRL版本(请参阅Native WinRT Inheritance以及Windows Runtime C++ Template Library (WRL),其中包含指向WRL和WinRT的各种支持主题的链接。
(
ComPtr
是一个WRL智能指针。它可以自动化COM的某些方面 否则快速繁琐。它类似于ATL的CComPtr
CComPtr
隐式执行的一些操作现在需要显式 代码,主要是因为那些隐式操作负责a 代码中的很多错误都是由那些不太懂的人编写的CComPtr
有效。使用新的ComPtr
,无法理解它 工作更有可能导致编译器错误,而不是运行时错误。)
以及ComPtr in the DirectXTK wiki
Microsoft::WRL::ComPtr
是COM对象的C ++模板智能指针 在Windows运行时(WinRT)C ++编程中广泛使用。 它也适用于Win32桌面应用程序。它类似于ATL的CComPtr
有一些有用的改进。Microsoft::WRL:::ComPtr
在 Windows 8.x SDK和Windows 10 SDK,与ATL不同,是 使用Visual Studio的Express版本时可用。它被使用了 广泛地在DirectX工具包中正确处理COM引用 计算维护。
#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);
}