c++ - 如何在 C++ 中将 char* 缓冲区包装在 WinRT IBuffer 中

标签 c++ windows-runtime

我想实现一个包装 char* 缓冲区的 C++ WinRT IBuffer,因此我可以将它与接受 IBuffer^ 参数的 WinRT WriteAsync/ReadAsync 操作一起使用。

编辑 1(说明)

我想避免数据复制。

最佳答案

大部分复制自http://jeremiahmorrill.wordpress.com/2012/05/11/http-winrt-client-for-c/但适合直接包装我自己的 byte[]:

NativeBuffer.h:

#pragma once

#include <wrl.h>
#include <wrl/implements.h>
#include <windows.storage.streams.h>
#include <robuffer.h>
#include <vector>

// todo: namespace

class NativeBuffer : 
    public Microsoft::WRL::RuntimeClass<Microsoft::WRL::RuntimeClassFlags<Microsoft::WRL::RuntimeClassType::WinRtClassicComMix>,
    ABI::Windows::Storage::Streams::IBuffer,
    Windows::Storage::Streams::IBufferByteAccess>
{
public:
    virtual ~NativeBuffer()
    {
    }

    STDMETHODIMP RuntimeClassInitialize(byte *buffer, UINT totalSize)
    {
        m_length = totalSize;
        m_buffer = buffer;

        return S_OK;
    }

    STDMETHODIMP Buffer(byte **value)
    {
        *value = m_buffer;

        return S_OK;
    }

    STDMETHODIMP get_Capacity(UINT32 *value)
    {
        *value = m_length;

        return S_OK;
    }

    STDMETHODIMP get_Length(UINT32 *value)
    {
        *value = m_length;

        return S_OK;
    }

    STDMETHODIMP put_Length(UINT32 value)
    {
        m_length = value;

        return S_OK;
    }

private:
    UINT32 m_length;
    byte *m_buffer;
};

创建 IBuffer:

Streams::IBuffer ^CreateNativeBuffer(LPVOID lpBuffer, DWORD nNumberOfBytes)
{
    Microsoft::WRL::ComPtr<NativeBuffer> nativeBuffer;
    Microsoft::WRL::Details::MakeAndInitialize<NativeBuffer>(&nativeBuffer, (byte *)lpBuffer, nNumberOfBytes);
    auto iinspectable = (IInspectable *)reinterpret_cast<IInspectable *>(nativeBuffer.Get());
    Streams::IBuffer ^buffer = reinterpret_cast<Streams::IBuffer ^>(iinspectable);

    return buffer;
}

以及读取数据的调用(lpBuffer是byte[]):

Streams::IBuffer ^buffer = CreateNativeBuffer(lpBuffer, nNumberOfbytes);
create_task(randomAccessStream->ReadAsync(buffer, (unsigned int)nNumberOfBytesToRead, Streams::InputStreamOptions::None)).wait();

我不太确定 ComPtr 是否需要清理,因此欢迎任何有关内存管理的建议。

关于c++ - 如何在 C++ 中将 char* 缓冲区包装在 WinRT IBuffer 中,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10520335/

相关文章:

xaml - 按钮样式看起来像应用栏按钮

windows-runtime - ApplicationPageBackgroundThemeBrush 不工作?

php - 在 VS15 中编译 PHP7 时找不到 bison.exe

C++ 从 Linux 上的剪贴板获取字符串

c++ - LPTSTR Losing Scope,变通无效 (C++)

c++ - 执行期间定期保存数据

C++ 未定义类型错误

database - WinRT SQLite 加密

c# - Kinect V2 背景去除 - 在脚和头发上切割像素

windows-runtime - HockeyApp 在 Windows Phone 上按下后退按钮时崩溃