Подтвердить что ты не робот

Получение массива байтов из Windows:: Storage:: Streams:: IBuffer

У меня есть объект, который реализует интерфейс Windows::Storage::Streams::IBuffer, и я хочу получить из него массив байтов, однако, глядя на документацию, этот интерфейс выглядит довольно бесполезным, и в документации нет какой-либо ссылки на какой-либо другой класс, который может быть объединен с этим интерфейсом для достижения моей цели. Все, что я нашел до сих пор с google, - это ссылка на класс .Net WindowsRuntimeBufferExtensions, но я использую С++, так что это тоже тупик,

Может кто-нибудь подскажет, как получить массив байтов из Windows::Storage::Streams::IBuffer в С++?

4b9b3361

Ответ 1

Вы можете использовать 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

Ответ 2

Также проверьте этот метод:

IBuffer → Платформа:: Массив
CryptographicBuffer.CopyToByteArray

Платформа:: Массив → IBuffer
CryptographicBuffer.CreateFromByteArray

В качестве побочного примечания, если вы хотите создать Platform::Array из простого массива С++, вы можете использовать Platform::ArrayReference, например:

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

Ответ 3

Это версия С++/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 и WriteOnlyArray (С++/CX).

Ответ 4

Как упоминалось ранее, WindowsRuntimeBufferExtensions из пространства имен System::Runtime::InteropServices::WindowsRuntime доступно только для приложений .Net, а не для собственных приложений на С++.

Возможным решением было бы использовать 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];

    (...)
}

Ответ 5

Это должно работать с расширениями 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

Ответ 6

Поскольку этот вопрос помечен , здесь решение с использованием C++/WinRT. По сути, он делает то же самое, что и этот ответ, но гораздо более доступен. (Недокументированный) помощник data() в проекции IBuffer выполняет всю тяжелую работу:

uint8_t* GetPointerToPixelData(::winrt::Windows::Storage::Streams::IBuffer const& buffer)
{
    return buffer.data();
}

Там нет, к сожалению, нет официальной документации (пока), и я наткнулся только через это в примере кода для WritableBitmap.PixelBuffer свойства (не забудьте выбрать "C++/WinRT" из выпадающего списка языков в правом верхнем углу).

Аналогичное решение (запрос интерфейса IBufferByteAccess) также доступно из этой записи документации при выборе "C++/CX" из выпадающего списка языков.