Эквивалент Платформы :: IBoxArray в C ++ / WinRT - PullRequest
0 голосов
/ 01 марта 2019

В настоящее время я портирую приложение UWP с C ++ / CX на C ++ / WinRT.Я столкнулся с safe_cast<Platform::IBoxArray<byte>^>(data), где data имеет тип Windows::Foundation::IInspectable ^.

Я знаю, что safe_cast представлен методом as<T>, и я знаю, что есть функции для бокса (winrt::box_value) и распаковка (winrt::unbox_value) в WinRT / C ++.

Однако мне нужно знать эквивалент Platform::IBoxArray для выполнения приведения (QueryInterface).Согласно https://docs.microsoft.com/de-de/cpp/cppcx/platform-iboxarray-interface?view=vs-2017, IBoxArray является эквивалентом C ++ / CX Windows::Foundation::IReferenceArray, но winrt::Windows::Foundation::IReferenceArray ...

нет обновления для nackground: Что яя пытаюсь добиться получения извлечения преобразования вида, прикрепленного HoloLens к каждому образцу Media Foundation со своей камеры.Мой код основан на https://github.com/Microsoft/HoloLensForCV,, и у меня действительно все работает, кроме этого последнего шага.Проблема находится вокруг этого куска кода:

static const GUID MF_EXTENSION_VIEW_TRANSFORM = {
    0x4e251fa4, 0x830f, 0x4770, 0x85, 0x9a, 0x4b, 0x8d, 0x99, 0xaa, 0x80, 0x9b
};

// ...

// In the event handler, which receives const winrt::Windows::Media::Capture::Frames::MediaFrameReader& sender:

auto frame = sender.TryAcquireLatestFrame();
// ...

if (frame.Properties().HasKey(MF_EXTENSION_VIEW_TRANSFORM)) {
    auto /* IInspectable */ userData = frame.Properties().Lookup(MF_EXTENSION_VIEW_TRANSFORM);

    // Now I would have to do the following:
    // auto userBytes = safe_cast<Platform::IBoxArray<Byte> ^>(userData)->Value;
    //viewTransform = *reinterpret_cast<float4x4 *>(userBytes.Data);
}

Ответы [ 2 ]

0 голосов
/ 05 августа 2019

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

auto user_data = source.Info().Properties().Lookup(c_MF_MT_USER_DATA); // type documented as 'array of bytes'
auto source_name = user_data.as<Windows::Foundation::IReferenceArray<std::uint8_t>>(); // Trial and error to get the right specialization of IReferenceArray
winrt::com_array<std::uint8_t> arr;
source_name.GetUInt8Array(arr);
winrt::hstring source_name_str{ reinterpret_cast<wchar_t*>(arr.data()) };

В частности, вы можете заменить safe_cast на .as<Windows::Foundation::IReferenceArray<std::uint8_t> длямассив байтов в штучной упаковке.Тогда я подозреваю, что выполнение того же приведения, что и у меня (за исключением float4x4 * вместо wchar_t *) будет работать для вас.

Флаг / ZW не требуется для моего примера выше.

0 голосов
/ 06 марта 2019

Не могу поверить, что это действительно сработало, но используя информацию из https://docs.microsoft.com/de-de/windows/uwp/cpp-and-winrt-apis/interop-winrt-cx,, я нашел следующее решение:

Включите «Использовать расширение среды выполнения Windows» через / ZW и используйте следующеепреобразование:

auto abi = reinterpret_cast<Platform::Object ^>(winrt::get_abi(userData));
auto userBytes = safe_cast<Platform::IBoxArray<byte> ^>(abi)->Value;
viewTransform = *reinterpret_cast<float4x4 *>(userBytes->Data);

К сожалению, у этого решения есть недостаток: генерируется предупреждение

C4447: обнаружена «основная» подпись без модели потоковПопробуйте использовать 'int main (Platform :: Array ^ args)'.

Но сейчас я могу с этим смириться ...

...