首页 > 解决方案 > 在从 c++/cx 移植到 c++/winrt 时实现 Windows 运行时接口以供本地使用时出错

问题描述

更新

根据 Ryan Shepherd 的回复,我将代码更改为:

class DerivedClass : winrt::implements<DerivedClass, BaseClass> {
public:
DerivedClass(winrt::FrameworkElement& control) : 
5===>implements_type(control) {}

static winrt::com_ptr<DerivedClass> from(winrt::FrameworkElement control) { 
    control ? control.Tag().try_as<SvgCanvasController>() : nullptr;
}
}

现在我得到一个错误:

没有构造函数实例 "winrt::implements<D, I, ...>::implements [with D=DerivedClass, I=BaseClass]" 匹配参数列表参数类型是:(winrt::Windows::UI:: Xaml::FrameworkElement)。

我确实定义了 BaseClass 构造函数,它将 &FrameworkElement 作为参数。所以我不确定我得到这个错误是什么。

原文

我在 C++/CX 中有这个:

ref class DerivedClass sealed : public BaseClass {
public:
explicit DerivedClass(Windows::UI::Xaml::FrameworkElement^ &control)
    : BaseClass(control) {}

static DerivedClass from(Windows::UI::Xaml::FrameworkElement^ control) {
    return control ? dynamic_cast<DerivedClass>(control->Tag) : nullptr;
}   
}

当我尝试将其转换为 c++/winrt

class DerivedClass : winrt::implements<DerivedClass, BaseClass> {
public:
1===>DerivedClass(winrt::FrameworkElement& control) : BaseClass(control) 
2===>{
}

static DerivedClass from(winrt::FrameworkElement control) { 
    if (control)
 3===>       return control.Tag().try_as<SvgCanvasController>();
    else
 4===>       return nullptr;
}

这里有几个问题我想讨论和理解。如上所述,我收到以下错误:

1

BaseClass 不是 DerivedClass 类的非静态数据成员或基类

2

winrt::implements<DerivedClass, BaseClass> 的默认构造函数不能被引用——它是一个被删除的函数

3

没有合适的用户定义从 winrt::impl::com_ref<DerivedClass> 到 DerivedClass 的转换

4

不存在从 std::nullptr_t 转换为 DerivedClass 的合适构造函数

希望对这些错误有一些想法。

我知道我创建了一个 DerivedClass 对象

auto obj = winrt::make<DerivedClass>();

问题:

  1. 如何正确编写构造函数?
  2. 如何像在 C++/CX 中那样将参数传递给基类构造函数?
  3. 如何处理 from() 函数定义中的错误。

标签: uwpuwp-xamlc++-cxc++-winrtcppwinrt

解决方案


关于第一个错误,DerivedClass不继承自BaseClass,它继承自winrt::implements<DerivedClass, BaseClass>,然后派生自BaseClass。孙子类不能直接初始化它的祖父类——它大部分都通过它的直接基类型。幸运的是,C++/WinRT 提供了一个帮助类型,winrt::implements因此您不必重复所有这些模板参数。因此,您的构造函数应如下所示:

#include <winrt/Windows.Foundation.h>
#include <winrt/Windows.UI.Xaml.h>

using namespace winrt;
using namespace winrt::Windows::Foundation;
using namespace winrt::Windows::UI::Xaml;

struct BaseType : implements<BaseType, IInspectable>
{
    explicit BaseType(FrameworkElement const&)
    {}
};

struct DerivedType : implements<DerivedType, BaseType>
{
    explicit DerivedType(FrameworkElement const& arg)
        : implements_type(arg)
    {}
};

int main()
{
    make<DerivedType>(FrameworkElement{ nullptr });
}

此代码为我成功编译。

其他三个错误是由于您试图直接在堆栈上返回实现类型。这些对象是引用计数的,并且必须在堆上分配,由于调用 out ,您似乎理解了这一点winrt::makeDerivedClass但是等式的其余部分是,您需要返回而不是返回 a ,winrt::com_ptr<DerivedClass>结果如下:

static winrt::com_ptr<Derived> from(winrt::FrameworkElement const& arg)
{
  return arg ? arg.Tag().try_as<DerivedClass>() : nullptr;
}

推荐阅读