Uwp Can';t激活IDL中定义的投影类型

Uwp Can';t激活IDL中定义的投影类型,uwp,windows-runtime,c++-winrt,Uwp,Windows Runtime,C++ Winrt,我试图在IDL中定义一个Windows运行时类型,并使用它的投影类型。从默认生成的空白应用程序UWP项目(称为“空白应用程序”)开始,我添加了“MyControl.idl”: 编译解决方案,然后将MyControl.h和MyControl.cpp从生成的文件/源复制到项目根目录 我包含了投影类型的标题,并将以下代码添加到App::OnLaunched: #包括 ... 无效应用程序::仅启动(启动ActivatedEventArgs const&e) { 自动常量myControl{winrt:

我试图在IDL中定义一个Windows运行时类型,并使用它的投影类型。从默认生成的空白应用程序UWP项目(称为“空白应用程序”)开始,我添加了“MyControl.idl”:

编译解决方案,然后将MyControl.h和MyControl.cpp从生成的文件/源复制到项目根目录

我包含了投影类型的标题,并将以下代码添加到
App::OnLaunched

#包括
...
无效应用程序::仅启动(启动ActivatedEventArgs const&e)
{
自动常量myControl{winrt::BlankApp::myControl()};
...
这一切都编译和链接良好。在运行时,它抛出一个
hresult\u错误
(0x80040154:REGDB\u E\u CLASSNOTREG类未注册)

异常引发点的调用堆栈顶部如下所示:

<代码> BlankApp .exe!Wrr::HReultTyErr::HRESultTyError(const HESultCode = ReqBdjeE.CaseNoTeTG类未注册,WRRT::HRESUTTHErrex::FixO-Aivit t={Sale= {}})2977行C++符号加载。 BlankApp .exe!Wrt::PosixHeREST(const HESREST结果= ReqBudEyCalthNoTrg类未注册)加载3211行C++符号。 BlankApp .exe!Wrr::CuffiHeREST(HESREST结果= ReqBudEyCalthNoTrg类未注册)加载3261行C++符号。 BlankApp .exe!Wrr::IMPL::GETHActudioToFiffy.()7375行C++符号加载。 BlankApp .exe!Wrr::IMPL::FaseYyCaseEnEng::GET()7448行C++符号加载。 BlankApp .exe!Wrr::GETHActudioToFiffy.()7520行C++符号加载。 BlankApp .exe!Wrr::BlankApp::MyCudith::MyCu管()74行C++符号加载。 BlankApp .exe!WINR:::BlankApp::实现:App::OnDead(const WINRT::Windows::ApvestMeimult::Ac激活::ActudiActudieDeaveTrass&e= {…})50行C++符号加载。 module.g.cpp被编译到应用程序中,并包含以下代码:

HRESULT\u stdcall WINRT\u GetActivationFactory(hs字符串classId,void**factory)
{
尝试
{
*工厂=空PTR;
wchar_t const*const name=WindowsGetStringRawBuffer(classId,nullptr);
如果(0==wcscmp(名称,L“BlankApp.MainPage”))
{
*factory=winrt::detach_abi(winrt::make());
返回S_OK;
}
如果(0==wcscmp(名称,L“BlankApp.MyControl”))
{
*factory=winrt::detach_abi(winrt::make());
返回S_OK;
}
#ifdef-WRL-U模块_
return::Microsoft::WRL::Module::GetModule().GetActivationFactory(classId,reinterpret_cast(factory));
#否则
将winrt::hresult_类_not_available()返回给_abi();
#恩迪夫
}
捕获(…)
{
返回winrt::to_hresult();
}
}

因此,很明显,我的类型没有被Windows运行时注册以供查找,即使所有内容似乎都在它需要的位置。是否缺少一些注册步骤?或者UWP应用程序甚至支持这一点,而不是Windows运行时组件?

您可能需要将该类添加到appx清单中

中有一个示例。需要添加以下元素:


BlankApp.exe
要允许Windows运行时检索激活工厂,还需要从可执行文件中导出
DllGetActivationFactory
符号。这可以通过将以下.def文件添加到项目中来完成:

导出
DllCanUnloadNow=WINRT_CanUnloadNow PRIVATE
DllGetActivationFactory=WINRT\u GetActivationFactory PRIVATE

添加
元素(指定可执行文件的路径以及类型名称/线程模型)将错误更改为0x800401F9(
CO_E_ERRORINDLL
)。可能需要导出
WINRT\u GetActivationFactory
符号(就像在Windows运行时组件中一样)。强制导出不会更改结果。尝试激活类型失败,错误代码为0x800401F9。很糟糕,我正在导出装饰符号。使用.def文件导出
DllGetActivationFactory
(和
DllCanUnloadNow
)似乎已修复该问题。我不确定这是否安全,或者是否有其他方法可以获得所需的功能。def文件是映射这些导出的受支持的方法。如果从市场()安装VSIX并创建“新的Windows运行时组件(C++/WinRT)”项目中,您将看到def文件是作为模板的一部分为您创建的。我知道,使用.def文件是从可执行映像导出符号的受支持的方式。我担心的是,是否从应用程序导出这些符号(相对于组件)是安全的。只是觉得为一个类型声明一个扩展点是不对的,它是应用程序实现内部的。我也不知道组件有什么特别之处,这样系统就可以在没有.appxmanifest的情况下进行类型工厂查找。手动导出
Dll*
符号似乎不是必需的(更多?)。这些导出是由生成的文件
App.xaml.g.hpp
通过
#pragma
指令提供的。我不知道这是由于更新了VSIX工具链,还是由于项目中的某些更改导致.hpp文件被拉入。
namespace BlankApp
{
    [default_interface]
    runtimeclass MyControl : Windows.UI.Xaml.Controls.Control
    {
        MyControl();
    }
}
BlankApp.exe!winrt::hresult_error::hresult_error(const HRESULT code=REGDB_E_CLASSNOTREG Class not registered, winrt::hresult_error::from_abi_t __formal={...}) Line 2977  C++ Symbols loaded.
BlankApp.exe!winrt::throw_hresult(const HRESULT result=REGDB_E_CLASSNOTREG Class not registered) Line 3211  C++ Symbols loaded.
BlankApp.exe!winrt::check_hresult(HRESULT result=REGDB_E_CLASSNOTREG Class not registered) Line 3261    C++ Symbols loaded.
BlankApp.exe!winrt::impl::get_activation_factory<winrt::BlankApp::MyControl,winrt::Windows::Foundation::IActivationFactory>() Line 7375 C++ Symbols loaded.
BlankApp.exe!winrt::impl::factory_cache_entry<winrt::BlankApp::MyControl,winrt::Windows::Foundation::IActivationFactory>::get() Line 7448   C++ Symbols loaded.
BlankApp.exe!winrt::get_activation_factory<winrt::BlankApp::MyControl,winrt::Windows::Foundation::IActivationFactory>() Line 7520   C++ Symbols loaded.
BlankApp.exe!winrt::BlankApp::MyControl::MyControl() Line 74    C++ Symbols loaded.
BlankApp.exe!winrt::BlankApp::implementation::App::OnLaunched(const winrt::Windows::ApplicationModel::Activation::LaunchActivatedEventArgs & e={...}) Line 50   C++ Symbols loaded.