我正在使用一个示例 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()
返回的缓冲区,我正在使用一个函数,如果在网络上找到其来源 获取指向数据缓冲区 (C++/CX) 的指针,这类似于从 Windows 中获取字节数组中的答案::存储::流::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
的指针。请参阅获取指向数据缓冲区的指针 (C++/CX)。另请参阅 COM 编码实践 有关IID_PPV_ARGS()
宏和 ATL 智能指针类CComPtr
的信息。另请参阅查询接口:在对象中导航。
ComPtr
是 ATLCComPtr
的 WRL 版本(请参阅本机 WinRT 继承以及 Windows 运行时C++模板库 (WRL),其中包含指向 WRL 和 WinRT 的各种支持主题的链接)。
(
ComPtr
是一个 WRL 智能指针。它自动化了 COM 的某些方面 否则变得乏味很快。它类似于ATL的CComPtr
,虽然 隐式执行的某些操作现在CComPtr
显式执行 代码,主要是因为这些隐式操作负责 代码中的许多错误是由那些并不真正理解的人编写的CComPtr
有效。随着新ComPtr
,一个不明白它是如何的 Works 比运行时错误更有可能导致编译器错误。
以及 DirectXTK wiki 中的 ComPtr
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);
}