【问题标题】:Equivalent of Platform::IBoxArray in C++/WinRTC++/WinRT 中 Platform::IBoxArray 的等价物
【发布时间】:2019-08-05 18:58:29
【问题描述】:

我目前正在将 UWP 应用程序从 C++/CX 移植到 C++/WinRT。我遇到了safe_cast<Platform::IBoxArray<byte>^>(data),其中data 的类型为Windows::Foundation::IInspectable ^

我知道safe_castas<T> 方法表示,并且我知道在WinRT/C++ 中有装箱(winrt::box_value) 和拆箱(winrt::unbox_value) 的函数。

但是,我需要知道 Platform::IBoxArray 的等价物才能执行强制转换 (QueryInterface)。根据https://docs.microsoft.com/de-de/cpp/cppcx/platform-iboxarray-interface?view=vs-2017IBoxArrayWindows::Foundation::IReferenceArray的C++/CX等价物,但没有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);
}

【问题讨论】:

  • 您要使用什么 API?
  • 我正在尝试从 Media Foundation 示例中提取 HoloLens 视图转换 - 此代码使用我从 Microsofts C++/CX 示例中获得的自定义 GUID 来获取 IInspectable,然后转换为 IBoxArray 然后 reinterpret_casted 转换为 float4x4 矩阵。所以问题是:我需要知道第一次转换的接口,但我发现没有办法从调试器中获取它......
  • 我不熟悉那个 API,但你可能想试试Windows::Foundation::IReferenceArray&lt;T&gt;

标签: windows-runtime c++-winrt


【解决方案1】:

我还致力于将一些代码从 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&lt;Windows::Foundation::IReferenceArray&lt;std::uint8_t&gt; 以获得盒装字节数组。然后,我怀疑做和我一样的演员表(除了 float4x4* 而不是 wchar_t*)对你有用。

上面的示例不需要 /ZW 标志。

【讨论】:

  • 非常有帮助,谢谢。不敢相信这似乎没有记录在任何地方。对于其他类型的数组(例如String[]),请查看IReferenceArray 上的方法列表:docs.microsoft.com/en-us/uwp/api/…
  • 我最终找到了时间来测试这个,同时将我的代码移植到 HoloLens 2。这正是我想要的 - 谢谢!
【解决方案2】:

我不敢相信这真的有效,但使用来自 https://docs.microsoft.com/de-de/windows/uwp/cpp-and-winrt-apis/interop-winrt-cx 的信息,我想出了以下解决方案:

通过 /ZW 启用“使用 Windows 运行时扩展”并使用以下转换:

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)'。

但现在,我可以忍受它......

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-04-02
    • 2021-10-15
    • 2013-10-20
    • 2011-04-10
    • 2021-12-02
    • 2010-09-14
    相关资源
    最近更新 更多