2012-05-09 19 views
8

我想實現一個C++的WinRT IBuffer它包裝一個char *緩衝區,這樣我就可以接受的IBuffer ^參數的WinRT WriteAsync/ReadAsync操作使用它。如何包裝一個char *緩衝區++一個WinRT中IBuffer用C

編輯1(說明)

我想避免數據複製。

+0

如果該函數可以採取陣列此外,這是一個備用(也許更容易)路線:http://stackoverflow.com/a/16645877/588476 –

回答

9

大多來自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是字節[]):

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

我不敢肯定,如果ComPtr需要一些清理,因此,歡迎有關內存管理的任何建議。

+0

'm_buffer =新字節[totalSize];'我看到'new';我沒有看到任何'刪除'。如果將底層緩衝區銷燬,將來通過「NativeBuffer」訪問它的嘗試將失敗(如何做到這一點取決於它的使用方式),這將是很好的做法。 'nativeBuffer.Get()''reinterpret_cast'到'Inspectable *'應該是不必要的。 –

+0

是的,抱歉,那部分不應該在那裏。我更新了答案,以反映這一點,使用COM構造函數設置字節[]應該是。 – pfo

+0

我會嘗試這個解決方案,當我找到一些時間,謝謝。 –

5

這應該工作:

// Windows::Storage::Streams::DataWriter 
// Windows::Storage::Streams::IBuffer 
// BYTE = unsigned char (could be char too) 
BYTE input[1024] {}; 

DataWriter ^writer = ref new DataWriter(); 
writer->WriteBytes(Platform::ArrayReference<BYTE>(input, sizeof(input)); 
IBuffer ^buffer = writer->DetachBuffer(); 
相關問題