Я получаю неразрешенный внешний символ winrt_make_ * при попытке скомпилировать пустое приложение C ++ / WinRT из XamlApplication - PullRequest
0 голосов
/ 05 февраля 2020

Я пытаюсь следовать руководству здесь: UWP Xaml API хостинга.

Я нахожусь в той части руководства, где я должен создать пустое приложение, которое определяет XamlApplication приложение. Я определил его в своем заголовке (.h) как:

#pragma once
#include "App.xaml.g.h"
namespace winrt::UI_Host::implementation
{
    struct App : Microsoft::Toolkit::Win32::UI::XamlHost::XamlApplicationT<App>
    {
        App();
        ~App();
    };
}

Мой. cpp файл имеет следующее определение:

#include "pch.h"
#include "App.h"
using namespace winrt;
using namespace Windows::ApplicationModel;
using namespace Windows::ApplicationModel::Activation;
using namespace Windows::Foundation;
using namespace Windows::UI::Xaml;
using namespace Windows::UI::Xaml::Controls;
using namespace Windows::UI::Xaml::Navigation;
using namespace UI_Host;
using namespace UI_Host::implementation;

winrt::UI_Host::implementation::App::App()
{
    Initialize();
}

winrt::UI_Host::implementation::App::~App()
{
    Close();
}

Если я оставлю свой файл .IDL как :

namespace UI_Host{}

Он прекрасно компилируется, но я не могу использовать класс App в моей программе Win32. Поэтому я изменил файл IDL на этот:

namespace UI_Host
{
    [default_interface]
    runtimeclass App : Microsoft.Toolkit.Win32.UI.XamlHost.XamlApplication
    {
        App();
    }
}

Но теперь он не будет компилироваться. Я получаю ошибку при компиляции:

>module.g.obj : error LNK2019: unresolved external symbol "void * __cdecl winrt_make_UI_Host_App(void)" (?winrt_make_UI_Host_App@@YAPEAXXZ) referenced in function "void * __cdecl winrt_get_activation_factory(class std::basic_string_view<wchar_t,struct std::char_traits<wchar_t> > const &)" (?winrt_get_activation_factory@@YAPEAXAEBV?$basic_string_view@_WU?$char_traits@_W@std@@@std@@@Z)

Кто-нибудь знает почему?

1 Ответ

1 голос
/ 05 февраля 2020

C ++ / WinRT 2.0 внесло принципиальное изменение для поддержки Оптимизированных компонентов . Используется при передаче -optimize в cppwinrt.exe. Эта опция включена по умолчанию для новых проектов.

Для критического изменения необходимо, чтобы авторы компонентов #include сгенерировали файл реализации в модуль компиляции, который реализует этот конкретный тип. В вашем случае вам нужно #include "App.g.cpp" в приложение. cpp (убедитесь, что #include это после заголовочного файла App.h ).

Чтобы ваш код компилировался с флагом -optimize и без него, вы можете условно включить App.g. cpp:

#include "App.h"

#if __has_include("App.g.cpp")
#    include "App.g.cpp"
#endif

Для удобства усвоения уроков вы можете прочитайте запись в блоге Рэймонда Чена под названием Почему мой проект C ++ / WinRT получает ошибки вида "Неразрешенный внешний символ void* __cdecl winrt_make_YourNamespace_YourClass(void)"? .

...