2012-05-09 2 views
8

char * 버퍼를 래핑하는 C++ WinRT IBuffer를 구현하여 IBuffer^매개 변수를 허용하는 WinRT WriteAsync/ReadAsync 작업과 함께 사용할 수 있습니다.C++에서 WinRT IBuffer에 char * 버퍼를 래핑하는 방법

EDIT 1 (설명)

나는 데이터 사본을 피하려고.

+0

을 함수도 배열을 취할 수 있다면, 이것은 다른 (그리고 아마도 쉽게) 경로입니다 : http://stackoverflow.com/a/16645877/588476 –

답변

9

는 대부분 http://jeremiahmorrill.wordpress.com/2012/05/11/http-winrt-client-for-c/에서 복사하지만 직접 내 자신 바이트 [] 포장하도록 :

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 = new byte [totalSize];'나는'new'를 봅니다; 나는'delete'가 보이지 않습니다. 기본 버퍼가 파괴 될 때'NativeBuffer'를 통해 미래의 접근 시도가 실패 할 것입니다 (어떻게하는지는 사용 방법에 따라 다릅니다). 'nativeBuffer.Get()'에서'IInspectable *'로의 reinterpret_cast는 불필요합니다. –

+0

예, 죄송합니다. 해당 부분이 없어야합니다. 나는 이것을 반영하기 위해 COM 생성자를 사용하여 바이트 [1]을 설정해야하는 대답을 업데이트했습니다. – 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(); 
관련 문제