You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C++/WinRT调用返回IAsyncOperation/IList的C#/WinRT组件时类未注册

解决方案

1. 修正应用程序清单配置

你的清单文件存在核心错误:WinRT.Host.dll并非托管WinRT组件的正确宿主入口,需将你的C#组件DLL(如csharp_winrt.dll)作为<file>元素的目标,同时确保activatableClass的命名空间和类名完全匹配:

<?xml version="1.0" encoding="utf-8"?>
<assembly manifestVersion="1.0" xmlns="urn:schemas-microsoft-com:asm.v1">
    <assemblyIdentity version="1.0.0.0" name="sdk_demo.exe"/>
    <!-- 替换为你的C#组件DLL文件名 -->
    <file name="csharp_winrt.dll">
        <activatableClass
            name="csharp_winrt.CSharpWinrtInterface"
            threadingModel="both"
            xmlns="urn:schemas-microsoft-com:winrt.v1" />
    </file>
    <!-- 若依赖WinRT.Runtime.dll,需添加此条目 -->
    <file name="WinRT.Runtime.dll" />
</assembly>

2. 确保C#项目的CsWinRT配置完整

检查C#项目的.csproj文件,确认以下配置项正确:

  • 目标框架必须为Windows SDK兼容版本(如net6.0-windows10.0.19041.0或更高)
  • 启用CsWinRT组件并指定输出路径:
<Project Sdk="Microsoft.NET.Sdk">
  <PropertyGroup>
    <TargetFramework>net6.0-windows10.0.19041.0</TargetFramework>
    <CsWinRTComponent>true</CsWinRTComponent>
    <!-- 输出到C++项目可访问的路径 -->
    <OutputPath>..\cpp_winrt_project\output\</OutputPath>
  </PropertyGroup>
  <ItemGroup>
    <PackageReference Include="Microsoft.Windows.CsWinRT" Version="2.0.0" />
  </ItemGroup>
</Project>

3. 验证C++项目的依赖复制

确保C++项目输出目录包含以下文件:

  • 你的C#组件DLL(csharp_winrt.dll)
  • WinRT.Runtime.dll(CsWinRT核心运行时)
  • 生成的.winmd文件(csharp_winrt.winmd)

可通过添加生成后事件自动复制:

xcopy /Y "$(SolutionDir)csharp_winrt\bin\$(Configuration)\net6.0-windows10.0.19041.0\*.dll" "$(OutDir)"
xcopy /Y "$(SolutionDir)csharp_winrt\bin\$(Configuration)\net6.0-windows10.0.19041.0\*.winmd" "$(OutDir)"

4. 修正C++调用代码的拼写与输出逻辑

你的C++代码存在变量名拼写错误,且WinRT字符串需用宽字符输出:

#include "winrt/csharp_winrt.h"
#include <winrt/Windows.Foundations.h>
#include <iostream>

void testCSharpCall() {
  winrt::csharp_winrt::CSharpWinrtInterface csharp_winrt_interface;
  auto result = co_await csharp_winrt_interface.HelloAsync(); // 修正拼写错误
  std::wcout << result.c_str() << std::endl; // 使用std::wcout输出宽字符
}

5. 优化异步方法实现(可选)

无需用Task.Run包装,直接使用AsyncInfo.Run更符合WinRT规范:

using Windows.Foundation;
using System.Threading.Tasks;

namespace csharp_winrt {
  public sealed class CSharpWinrtInterface {
    public IAsyncOperation<string> HelloAsync() {
      return AsyncInfo.Run(async token => {
        await Task.Delay(2000, token);
        return "Hello World!";
      });
    }
  }
}

关键原因分析

当方法返回IAsyncOperation<T>等复杂WinRT类型时,WinRT需要完整的组件注册信息来加载托管运行时宿主;错误的清单配置会导致系统无法定位activatable类,从而抛出REGDB_E_CLASSNOTREG。而返回简单类型时,WinRT的类型解析逻辑更简化,因此可正常运行。

内容的提问来源于stack exchange,提问作者Vanilson Nogueira

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.20 01:53:16