2012-08-07 16 views
12

Tengo un objeto que implementa la interfaz Windows::Storage::Streams::IBuffer, y quiero obtener una matriz de bytes, sin embargo, al mirar la documentación, la interfaz parece bastante inútil, y la documentación no ofrece ninguna referencia a ninguna otra clase que pueda combinarse con esta interfaz para lograr mi propósito. Todo lo que he encontrado hasta ahora con google es una referencia a la clase .Net WindowsRuntimeBufferExtensions pero estoy usando C++, así que esto también es un callejón sin salida.Obteniendo una matriz de bytes de Windows :: Storage :: Streams :: IBuffer

¿Alguien puede dar una pista sobre cómo obtener una serie de bytes desde Windows::Storage::Streams::IBuffer en C++?

Respuesta

10

Usted puede utilizar IBufferByteAccess, a través de exóticos COM arroja: muestra

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; 

} 

Código copiado de http://cm-bloggers.blogspot.fi/2012/09/accessing-image-pixel-data-in-ccx.html

+0

Cambié mi implementación y estoy usando este enfoque ahora ya que mejora el rendimiento de mi aplicación. Gracias. –

0

Use the extension method like a static method:

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

@ user787913, yo estaba confundido en un primer momento también. – MSN

+5

@MSN WindowsRuntimeBufferExtensions es una clase en .NET framework, no se puede usar desde una aplicación nativa de C++ – yms

5

Como se ha mencionado antes, WindowsRuntimeBufferExtensions del espacio de nombres System::Runtime::InteropServices::WindowsRuntime sólo está disponible para aplicaciones .Net y no para aplicaciones nativas en C++.

Una posible solución sería utilizar 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' - lol, esto hizo mi día ... – Zak

7

Este es un C++/CX versión:

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; 
} 

Para obtener más información, vea Array and WriteOnlyArray (C++/CX).

9

También puedes ver este método:

IBuffer -> Plataforma :: Matriz
CryptographicBuffer.CopyToByteArray

Plataforma :: Array -> IBuffer
CryptographicBuffer.CreateFromByteArray

Como nota al margen, si quieres crear Platform::Array desde una matriz C++ simple puede usar Platform::ArrayReference, por ejemplo:

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

Gracias, esto me salvó un dolor de cabeza !, como referencia, ArrayReference está en el espacio de nombres de la plataforma. –

+1

ADVERTENCIA: sizeof (c) producirá el tamaño del puntero, no la longitud del hilo. –

3

Esto debería funcionar con extensiones 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

Casi no hay documentación sobre esta clase Platform :: ArrayReference, ¿dónde encontraste esta información si pudiera preguntar? –

+2

Aquí hay un ejemplo de MSDN https://msdn.microsoft.com/en-us/library/hh700131.aspx "Usar ArrayReference para evitar copiar datos" –

Cuestiones relacionadas