Ошибка при реализации интерфейса среды выполнения Windows для локального использования при переносе с c / cx на c / winrt

#uwp #uwp-xaml #c -cx #c -winrt #cppwinrt

#увп #uwp-xaml #c -cx #c -winrt #cppwinrt #uwp #c -cx

Вопрос:

Обновить:

Основываясь на ответе Райана Шепарда, я изменил свой код на:

 class DerivedClass : winrt::implements<DerivedClass, BaseClass> {
public:
DerivedClass(winrt::FrameworkElementamp; 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).

У меня действительно определен конструктор базового класса, который принимает в качестве аргумента amp;FrameworkElement. Поэтому я не уверен, что получаю эту ошибку.

Оригинал:

У меня было это в C / CX:

 ref class DerivedClass sealed : public BaseClass {
public:
explicit DerivedClass(Windows::UI::Xaml::FrameworkElement^ amp;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::FrameworkElementamp; control) : BaseClass(control) 
2===>{
}

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

Здесь есть несколько проблем, которые я хочу обсудить и понять. Как написано выше, я получаю следующие ошибки:

1

Базовый класс не является нестатическим элементом данных или базовым классом класса DerivedClass

2

невозможно ссылаться на конструктор winrt по умолчанию::implements<Производный класс, базовый класс> — это удаленная функция

3

Нет подходящего пользовательского преобразования из winrt::impl::com_ref<DerivedClass> в DerivedClass

4

не существует подходящего конструктора для преобразования из std::nullptr_t в DerivedClass

Хотелось бы услышать несколько мыслей по поводу этих ошибок.

Я понимаю, что я создаю объект DerivedClass как

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

Вопросы:

  1. Как мне правильно написать конструктор?
  2. Как я могу передать аргумент конструктору базового класса, как я делаю в C / CX?
  3. Как я могу справиться с ошибками в определении функции from().

Комментарии:

1. Модификатор доступа по умолчанию при управлении class является private . Либо сделайте это struct , либо укажите, что вы хотите использовать public ly.

Ответ №1:

Что касается первой ошибки, DerivedClass не наследуется от BaseClass , она наследуется от winrt::implements<DerivedClass, BaseClass> , которая затем является производной от BaseClass . Класс grandchild не может напрямую инициализировать своего прародителя — в большинстве случаев он проходит через свой непосредственный базовый тип. К счастью, 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 constamp;)
    {}
};

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

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

Этот код успешно компилируется для меня.

Остальные три ошибки связаны с тем, что вы пытаетесь вернуть тип реализации непосредственно в стек. Эти объекты подсчитываются по ссылкам и должны быть размещены в куче, что вы, кажется, понимаете из-за вызова winrt::make . Но остальная часть уравнения заключается в том, что вместо возврата a DerivedClass вам нужно вернуть winrt::com_ptr<DerivedClass> , в результате чего получится что-то вроде этого:

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

Комментарии:

1. Спасибо за ответ. когда я использую implements_type(control), я получаю следующую ошибку: «ни один экземпляр конструктора winrt::implements<D, I, …>::implements [с D=DerivedClass, I=BaseClass]» не соответствует списку аргументов. типы аргументов: (winrt::Windows::UI::Xaml::FrameworkElement). У меня действительно определен конструктор базового класса, который принимает в качестве аргумента amp;FrameworkElement. Итак, я не уверен, чего мне не хватает. Или если моего понимания там все еще не хватает.

2. Я подозреваю, что в вашем примере есть нечто большее, чем опубликовано. Я обновил приведенный выше код, чтобы имитировать код в вашем вопросе, и он успешно компилируется для меня.