【发布时间】:2023-04-11 06:47:01
【问题描述】:
我正在尝试将我现有的 C++/CX 代码转换为 C++/WinRT,以确定这是否能让我使用 Clang 编译该代码。但是,我很早就被困住了。
我需要转换的 C++/CX 代码用于构建 Direct3D 组件(基于 SwapChainPanel),该组件最终在用 C# 编写的 Windows UWP 应用程序中使用。我面临的问题是我无法将自定义的SwapChainPanel 转换为 C++/WinRT。
代码如下:
namespace Why::Does::This::Not::Work
{
[Windows::Foundation::Metadata::WebHostHidden]
public ref class BaseView : public Windows::UI::Xaml::Controls::SwapChainPanel
{
protected private:
BaseView();
// Lots of other stuff
};
}
namespace Why::Does::This::Not::Work
{
[Windows::Foundation::Metadata::WebHostHidden]
public ref class CustomView sealed : public BaseView
{
public:
CustomView();
// ...
event AnimationEventHandler^ AnimationStarted;
private protected:
// Lots of private protected stuff
};
}
namespace Why::Does::This::Not::Work
{
[Windows::Foundation::Metadata::WebHostHidden]
public ref class AnimationEventArgs sealed
{
public:
AnimationEventArgs() {}
AnimationEventArgs(int start, int end)
{
Start = start;
End = end;
}
property int Start;
property int End;
};
[Windows::Foundation::Metadata::WebHostHidden]
public delegate void AnimationEventHandler(Platform::Object^ sender, AnimationEventArgs^ e);
}
就我能够解释文档而言,我需要执行文档中If you're authoring a runtime class to be referenced in your XAML UI 下所述的操作。
因此,在我看来,我需要编写一个 IDL 文件才能生成所需的 COM 内容。但是,我什至无法编译骨架 IDL:
namespace Why
{
namespace Does
{
namespace This
{
namespace Not
{
namespace Work
{
runtimeclass CustomView : Windows::UI::Xaml::Controls::SwapChainPanel
{
CustomView();
}
}
}
}
}
}
当我试图编译上面的代码时,我得到的只是
error MIDL2025: [msg]syntax error [context]: expecting { near ":"
error MIDL2026: [msg]cannot recover from earlier syntax errors; aborting compilation
如果您认为这是一个愚蠢的问题,我深表歉意。我已经阅读了相应的文档,但我只是无法理解使用 C++/WinRT 时到底发生了什么。我在 C++ 方面有丰富的经验,但在 COM 方面的经验为零,这意味着理解 C++/WinRT 并非易事。
如果有人可以帮我将上述 C++/CX 代码翻译成 C++/WinRT,我将不胜感激。请不要只将我指向文档,这没有帮助。
编辑:
修改示例IDL代码如下成功编译:
namespace Why
{
namespace Does
{
namespace This
{
namespace Not
{
namespace Work
{
[default_interface]
runtimeclass CustomView : Windows.UI.Xaml.Controls.SwapChainPanel
{
CustomView();
}
}
}
}
}
}
但是,将用户控件暴露给另一种语言,在我的例子中是 C#,例如从 SwapChainPanel 继承的语言,比在 C++/CX 中做同样的事情要复杂得多。有一个 IDL 处理起来并不容易,因为周围似乎没有任何复杂的样本。该 IDL 生成了几个头文件,我不确定如何处理这些头文件,因为缺少文档并且示例很少。 C++/WinRT 不适合胆小的人,与 C++/CX 相比,它的复杂性要高得多。
在我看来,真正了解 C++/WinRT 有必要很好地掌握 COM,因为与 C++/CX 相比,C++/WinRT 在隐藏这些 COM 方面做得很差相关内部。在处理 DirectX 时尤其如此。再加上一个 IDL,它本身就很难处理,它的文档可能足以启动和运行简单的示例,但在移植完整的 C++/CX 应用程序时没有多大帮助。
在 C++/WinRT 中使用 C++/CX 做我们所做的事情并不经济,我们将继续使用 C++/CX,直到 C++/WinRT 变得更加更加用户友好。消除对 IDL 的需求(请参阅 https://wpdev.uservoice.com/forums/110705-universal-windows-platform/suggestions/36095386-get-rid-of-idl-for-c-winrt-components)也会有所帮助。
如果没有能够使用 Clang 编译我们的代码的前景,我什至不会考虑离开 C++/CX。微软不应该怀疑 C++/WinRT 的采用速度很慢。如果他们真的想改变,他们必须大大降低进入门槛。
【问题讨论】:
-
写了几十年的COM代码,我这里可能有点偏颇。但是,我的看法是,C++/WinRT 在隐藏所有 COM 基础方面做得非常。您永远不会看到任何
QueryInterface、AddRef或Release调用,您也不会接触到类型激活或工厂实现的细节。事实上,它把 COM 隐藏得太多了:当你通过值传递MyType时,它取决于命名空间,是通过值传递实现类型,还是指向实现类型的智能指针,语义上与传递相同-by-ref. -
不过,C++/WinRT 是一种具有挑战性的 Windows 运行时方法。进入的障碍可能看起来巨大,但它真的不是那么糟糕,一旦你玩了一段时间。我现在正在进行我的第二个 C++/WinRT 玩具项目,感觉就像编写 C# 代码,但具有 C++ 的灵活性和原始功能。我的建议:继续玩。
-
感谢您的 cmets。在这里获得其他意见会很有帮助,因为很难看到未来会发生什么。鉴于我们的时间限制,我只需要看看我能做些什么。
标签: c++-winrt