Uwp 如何通过Windows::Storage::Streams::DataWriter::WriteBuffer()将字节复制到Windows::Storage::Streams::Buffer或IBuffer以便输出

Uwp 如何通过Windows::Storage::Streams::DataWriter::WriteBuffer()将字节复制到Windows::Storage::Streams::Buffer或IBuffer以便输出,uwp,visual-studio-2017,c++-cx,Uwp,Visual Studio 2017,C++ Cx,我正在使用一个示例UWP C++/CX程序,该程序创建两个UDP网络通信线程,它们使用Windows::Storage::Streams::DataWriter和Windows::Storage::Streams::DataReader相互发送数据,同时更新显示来回数据的窗口 使用Platform::String变量以及DataWriter->WriteString()的初始实现工作正常。然而,现在我想实现一个二进制协议,该协议具有包含各种类型信息的可变长度缓冲区 DataReader->Rea

我正在使用一个示例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()
返回的缓冲区,我使用了一个函数,如果在web上找到该函数,其源代码与中的答案类似

#包括
字节*GetPointerToPixelData(IBuffer^pixelBuffer,无符号整数*长度)
{
如果(长度!=nullptr)
{
*长度=像素缓冲->长度;
}
//查询IBufferByte访问接口。
微软::WRL::ComPtr bufferByteAccess;
重新解释强制转换(pixelBuffer)->查询接口(IID_PPV_参数(&bufferByteAccess));
//检索缓冲区数据。
字节*像素=空PTR;
bufferByteAccess->Buffer(&pixels);
返回像素;
}
但是,我无法找到如何将本机结构复制到缓冲区中,以便使用
DataWriter->WriteBuffer()
将其发送出去


如果我有一些二进制数据结构,如何将该结构的内容复制到输出
Windows::Storage::Streams::Buffer
中,以便与
DataWriter->WriteBuffer()一起使用

似乎可以使用相同的函数来获取指向
缓冲区的指针,以便将数据从
缓冲区复制到本机内存区,也可以使用相同的函数来获取指针,以便将数据复制到
缓冲区。有关
IID\u PPV\u ARGS()
宏和ATL智能指针类
CComPtr
的信息,请参阅和另请参阅。我也看到了

ComPtr
是ATL
CComPtr
的WRL版本(请参阅,它还有指向WRL和WinRT的各种支持主题的链接)

ComPtr
是一个WRL智能指针。它自动化了COM的某些方面 否则会很快变得单调乏味。它类似于ATL的
CComPtr
一些隐式执行的
CComPtr
操作现在需要显式 代码,主要是因为这些隐式操作负责 代码中有很多错误,这些错误都是由那些并不真正理解如何编写的人编写的
CComPtr
工作。对于新的
ComPtr
,无法理解它是如何工作的 works更可能导致编译器错误,而不是运行时错误。)

以及

<> >代码:微软::WRL::COMPTR < /C> >是COM对象的C++模板智能指针 这在Windows运行时(WinRT)C++编程中被广泛使用。 它也适用于Win32桌面应用程序。它与ATL的类似
CComPtr
有一些有用的改进<代码>Microsoft::WRL:::ComPtr
处于 与ATL不同的是,Windows8.xSDK和Windows10SDK是 使用Visual Studio的快速版本时可用。它被使用 在DirectX工具包中广泛使用,以正确处理COM引用 计数维护


您也可以使用
dataWriter->WriteBytes()
写出字节,然后使用
Platform::Array
保存数据。@PeterTorr MSFT感谢您的建议。还有
ReadBytes()
吗?看起来有一个参数是
字节
数组和最大大小或容量。我想我已经固定了
缓冲区
方法,使用了一个以
字符串开始的示例。我认为
Buffer
方法的优点是处理可变的数据包大小,这是一个UDP客户机/服务器,
Buffer
可能更容易。但是,我正在复制的原始应用程序对UDP网络流量使用了一个较大的缓冲区大小。在IDL中,它表示为{pointer,size}对参数,但它也应该作为
Platform::Array
进行投影。@PeterTorr MSFT感谢您的链接,因为该页面上有指向。
#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;
}
#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;
}
// 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);

}