我想實現一個C++的WinRT IBuffer它包裝一個char *緩衝區,這樣我就可以接受的IBuffer ^參數的WinRT WriteAsync/ReadAsync操作使用它。如何包裝一個char *緩衝區++一個WinRT中IBuffer用C
編輯1(說明)
我想避免數據複製。
我想實現一個C++的WinRT IBuffer它包裝一個char *緩衝區,這樣我就可以接受的IBuffer ^參數的WinRT WriteAsync/ReadAsync操作使用它。如何包裝一個char *緩衝區++一個WinRT中IBuffer用C
編輯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是字節[]):
Streams::IBuffer ^buffer = CreateNativeBuffer(lpBuffer, nNumberOfbytes);
create_task(randomAccessStream->ReadAsync(buffer, (unsigned int)nNumberOfBytesToRead, Streams::InputStreamOptions::None)).wait();
我不敢肯定,如果ComPtr需要一些清理,因此,歡迎有關內存管理的任何建議。
'm_buffer =新字節[totalSize];'我看到'new';我沒有看到任何'刪除'。如果將底層緩衝區銷燬,將來通過「NativeBuffer」訪問它的嘗試將失敗(如何做到這一點取決於它的使用方式),這將是很好的做法。 'nativeBuffer.Get()''reinterpret_cast'到'Inspectable *'應該是不必要的。 –
是的,抱歉,那部分不應該在那裏。我更新了答案,以反映這一點,使用COM構造函數設置字節[]應該是。 – pfo
我會嘗試這個解決方案,當我找到一些時間,謝謝。 –
這應該工作:
// 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();
如果該函數可以採取陣列此外,這是一個備用(也許更容易)路線:http://stackoverflow.com/a/16645877/588476 –