如何将非原始类型从 C# winrt 组件返回到 C++?

问题描述 投票:0回答:1

我目前有一个工作项目,我正在使用 免注册 Winrt 在 win32 控制台应用程序中使用 C# WinRT 组件。一切工作正常,但当我尝试使用 C# 组件中的异步方法时,问题就出现了。由于

Task
不是 WinRT 类型,因此我四处寻找解决方案。那么从 C# WinRT 组件调用异步方法的正确方法是什么?

我使用 winmdidl.exe 和 midlrt.exe 为控制台应用程序创建 WinRT comp 头文件。我还包含了“Winrt/Windows.Foundation.h”。

我尝试过“如何在 Windows 运行时组件中公开异步方法”。这将构建,但在运行时会出现令人畏惧的错误(imo)

Class not registered
。这也是2014年的。

C# WinRT 组件:

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

namespace MyComp
{
    public sealed class MyLib
    {
        public static string OtherMethods()    // only working method
        {
            return "string";
        }

            // Below methods results with `Class not registered` error
        public static IAsyncOperation<string> TestAsync()    // I think this is the problem
        {
            return TestAsyncHelper().AsAsyncOperation();
        }

        private static async Task<string> TestAsyncHelper()
        {
            // do stuff here
            return "string";
        }
        
// ******* Update ****
        public static IDictionary<int, string> GetMapOfNames()
        {
            Dictionary<int, string> retval = new Dictionary<int, string>();
            retval.Add(1, "one");
            retval.Add(2, "two");
            retval.Add(3, "three");
            retval.Add(42, "forty-two");
            retval.Add(100, "one hundred");
            return retval;
        }
    }
}

更新

我注意到每个非原始的 WinRT 类型都会发生这种情况。我正在尝试实现

IList<int>
IDictionary<int, string>
,但这些都不起作用。我发现 “将托管类型传递到 Windows 运行时” 导致 “从组件返回托管类型”,但我尝试的每一次尝试都导致了
Class not registered
错误。在链接的文章中,它提到当将 .Net 类型传递给 WinRT 组件时,它会在另一端显示为相应的 WinRT 类型,这听起来应该可以工作。我也尝试过使用
IMap<int, string>
,但是
IMap<K, V> is inaccessible due to its protection level
会出错。我已经更新了示例代码。

c# .net windows-runtime c++-winrt winrt-component
1个回答
0
投票

我知道已经晚了几年,也许你自己已经找到了解决方案,但我也遇到了同样的问题几天并意识到了解决方案。

查看 CsWinRT 项目中的一些示例后,尤其是 AuthoringDemo,它有一个使用 C#/WinRT 项目 (AuthoringDemo) 的 C++ 控制台应用程序 (CppConsoleApp),我意识到我错过了标签的声明

 <CsWinRTWindowsMetadata>10.0.19041.0</CsWinRTWindowsMetadata>
存在于文件中
AuthoringDemo/AuthoringDemo.csproj
。此标记在 CsWinRT 文档中描述为 “指定 Windows 元数据的源”,其默认值应为
$(WindowsSDKVersion)
,但似乎从未设置此值,并且 C#/WinRT 投影也没有设置无法导出一些运行时声明。

使用正确的 SDK 版本添加此标签后(取决于您的项目设置),它识别

IAsyncAction
IList<>
IAsncOperation<>
以及可能所有其他运行时非原始投影。这个 AuthoringDemo.csproj 应该包含正确导出到 WinRT 所需的所有内容。

还值得注意的是,CppConsoleApp 有一个清单文件CppConsoleApp.exe.manifest,它必须声明您希望 WinRT 激活的 C# 类。您的 C++ 应用程序也应该类似。

© www.soinside.com 2019 - 2024. All rights reserved.