uwp - 无法激活 IDL 中定义的投影类型

标签 uwp windows-runtime c++-winrt

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

namespace BlankApp
{
    [default_interface]
    runtimeclass MyControl : Windows.UI.Xaml.Controls.Control
    {
        MyControl();
    }
}

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

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

#include <winrt/BlankApp.h>

...

void App::OnLaunched(LaunchActivatedEventArgs const& e)
{
    auto const myControl{ winrt::BlankApp::MyControl() };
    ...

这一切都编译和链接良好。在运行时,它会抛出 hresult_error (0x80040154:REGDB_E_CLASSNOTREG 类未注册)。

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

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.

module.g.cpp 被编译到应用程序中并包含以下代码:

HRESULT __stdcall WINRT_GetActivationFactory(HSTRING classId, void** factory)
{
    try
    {
        *factory = nullptr;
        wchar_t const* const name = WindowsGetStringRawBuffer(classId, nullptr);

        if (0 == wcscmp(name, L"BlankApp.MainPage"))
        {
            *factory = winrt::detach_abi(winrt::make<winrt::BlankApp::factory_implementation::MainPage>());
            return S_OK;
        }

        if (0 == wcscmp(name, L"BlankApp.MyControl"))
        {
            *factory = winrt::detach_abi(winrt::make<winrt::BlankApp::factory_implementation::MyControl>());
            return S_OK;
        }

#ifdef _WRL_MODULE_H_
        return ::Microsoft::WRL::Module<::Microsoft::WRL::InProc>::GetModule().GetActivationFactory(classId, reinterpret_cast<::IActivationFactory**>(factory));
#else
        return winrt::hresult_class_not_available().to_abi();
#endif
    }
    catch (...)
    {
        return winrt::to_hresult();
    }
}

很明显,我的类型没有注册供 Windows 运行时查找,尽管一切似乎都在它需要的地方。我是否缺少某些注册步骤?或者 UWP 应用程序(而不是 Windows 运行时组件)是否支持此功能?

最佳答案

您可能需要将该类添加到 appx list 中。

Extensions element documentation中有一个例子。以下Extension需要添加元素:

<Extensions>
  <Extension Category="windows.activatableClass.inProcessServer">
    <InProcessServer>
      <Path>BlankApp.exe</Path>
      <ActivatableClass ActivatableClassId="BlankApp.MyControl" ThreadingModel="both" />
    </InProcessServer>
  </Extension>
</Extensions>

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

EXPORTS
DllCanUnloadNow = WINRT_CanUnloadNow                    PRIVATE
DllGetActivationFactory = WINRT_GetActivationFactory    PRIVATE

关于uwp - 无法激活 IDL 中定义的投影类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50889858/

相关文章:

c# - 使用 MVVM 模式时,x :Bind to event handlers located in the ViewModel? 是否可以

c# - Windows 8 XAML 应用程序 - C++ 与 C# - 用户体验差异

c++ - 无法将运行时类绑定(bind)到 XAML T 必须是 WinRT 类型

c++ - 如何添加 C++/WinRT 按钮单击处理程序?

visual-studio - 如何将 UWP 部署到运行 Windows 10 操作系统的 Galaxy TabPro S?

c# - 在 UWP 应用程序中检测 sleep 事件或唤醒事件

uwp - 如何在 ConsoleApp 中添加对 Windows.Foundation.FoundationContract 的引用以解析类型 IPropertySet

c# - WinRT 中字段的正确命名约定是什么

c++ - 如何将元素添加到从另一个线程绑定(bind)到 XAML 的 IVector

c++ - 在cppwinrt中以编程方式创建图像按钮