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

时间:2018-04-16 02:49:49

标签: uwp visual-studio-2017 c++-cx

我正在使用示例UWP C ++ / CX程序创建两个UDP网络通信线程,这些线程使用Windows::Storage::Streams::DataWriterWindows::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()一起使用?

1 个答案:

答案 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);

}