2012-08-07 26 views
12

我有一個對象實現了接口Windows::Storage::Streams::IBuffer,我想從中獲取一個字節數組,但是在查看文檔時界面看起來很沒用,而且文檔沒有提供任何可以與這個界面相結合的其他類的引用來實現我的目的。到目前爲止我發現的所有與谷歌是一個參考。NET類WindowsRuntimeBufferExtensions但我使用C++,所以這也是一個死衚衕。從Windows獲取一個字節數組:: Storage :: Streams :: IBuffer

有人可以提供一個關於如何在C++中獲得Windows::Storage::Streams::IBuffer字節數組的提示嗎?

回答

10

可以使用IBufferByteAccess,通過異國COM轉換:

byte* GetPointerToPixelData(IBuffer^ buffer) 
{ 
    // Cast to Object^, then to its underlying IInspectable interface. 

    Object^ obj = buffer; 
    ComPtr<IInspectable> insp(reinterpret_cast<IInspectable*>(obj)); 

    // Query the IBufferByteAccess interface. 
    ComPtr<IBufferByteAccess> bufferByteAccess; 
    ThrowIfFailed(insp.As(&bufferByteAccess)); 

    // Retrieve the buffer data. 

    byte* pixels = nullptr; 
    ThrowIfFailed(bufferByteAccess->Buffer(&pixels)); 

    return pixels; 

} 

代碼示例從http://cm-bloggers.blogspot.fi/2012/09/accessing-image-pixel-data-in-ccx.html

+0

我改變了我的實現,現在我正在使用這種方法,因爲它提高了我的應用程序的性能。謝謝。 – 2013-02-01 20:28:16

0

Use the extension method like a static method

IBuffer *buffer; 
array<unsigned char>^ result= System::Runtime::InteropServices::WindowsRuntime::WindowsRuntimeBufferExtensions::ToArray(buffer); 
+0

@ user787913,我起初也感到困惑。 – MSN 2012-08-07 22:28:35

+5

@MSN WindowsRuntimeBufferExtensions是.Net框架中的一個類,它不能從本地C++應用程序中使用 – yms 2012-08-08 13:39:43

5

如前所述,WindowsRuntimeBufferExtensions從命名空間System::Runtime::InteropServices::WindowsRuntime僅適用於.Net應用程序,而不是本機C++應用程序。

一種可能的解決辦法是使用Windows::Storage::Streams::DataReader

void process(Windows::Storage::Streams::IBuffer^ uselessBuffer) 
{ 
    Windows::Storage::Streams::DataReader^ uselessReader = 
      Windows::Storage::Streams::DataReader::FromBuffer(uselessBuffer); 
    Platform::Array<Byte>^ managedBytes = 
         ref new Platform::Array<Byte>(uselessBuffer->Length); 
    uselessReader->ReadBytes(managedBytes);        
    BYTE * bytes = new BYTE[uselessBuffer->Length]; 
    for(int i = 0; i < uselessBuffer->Length; i++) 
     bytes[i] = managedBytes[i]; 

    (...) 
} 
+1

'uselessBuffer' - 大聲笑,這讓我的一天... – Zak 2015-12-03 02:02:25

7

這是一個C複製++/CX版本:

std::vector<unsigned char> getData(::Windows::Storage::Streams::IBuffer^ buf) 
{ 
    auto reader = ::Windows::Storage::Streams::DataReader::FromBuffer(buf); 

    std::vector<unsigned char> data(reader->UnconsumedBufferLength); 

    if (!data.empty()) 
     reader->ReadBytes(
      ::Platform::ArrayReference<unsigned char>(
       &data[0], data.size())); 

    return data; 
} 

欲瞭解更多信息,請參閱Array and WriteOnlyArray (C++/CX)

9

還要檢查這個方法:

IBuffer - >平臺::陣列
CryptographicBuffer.CopyToByteArray

平臺::陣列 - > IBuffer
CryptographicBuffer.CreateFromByteArray

作爲一個側面說明,如果你想從簡單的C++數組創建Platform::Array,您可以使用Platform::ArrayReference,例如:

char* c = "sdsd"; 
Platform::ArrayReference<unsigned char> arraywrapper((unsigned char*) c, sizeof(c)); 
+0

謝謝,這讓我很頭疼!作爲參考,ArrayReference位於Platform命名空間中。 – 2015-02-19 07:52:41

+1

警告:sizeof(c)將產生指針的大小,而不是字符串的長度。 – 2015-03-13 13:32:26

3

這應該與WinRT的擴展工作:

// Windows::Storage::Streams::DataReader 
// buffer is assumed to be of type Windows::Storage::Streams::IBuffer 
// BYTE = unsigned char 

DataReader^ reader = DataReader::FromBuffer(buffer); 

BYTE *extracted = new BYTE[buffer->Length]; 

// NOTE: This will read directly into the allocated "extracted" buffer 
reader->ReadBytes(Platform::ArrayReference<BYTE>(extracted, buffer->Length)); 

// ... do something with extracted... 

delete [] extracted; // don't forget to free the space 
+0

幾乎沒有關於此類Platform :: ArrayReference的文檔,如果我可能會問,您從哪裏找到這些信息? – 2015-03-23 13:48:39

+2

以下是來自MSDN的示例https://msdn.microsoft.com/en-us/library/hh700131.aspx「使用ArrayReference避免複製數據」 – 2015-04-10 13:45:55

相關問題