通过 Cpp/WinRT 项目模板创建一个 WinRT 组件工程 CppWinrtComponent.vcxproj,主要接口定义如下:

Copy
namespace CppWinrtComponent
{
[default_interface]
runtimeclass Class
{
Class();
String GetModule();
}
}
最终该项目 CppWinrtComponent 可以被编译生成两个 WinRT 组件的核心部分:

CppWinrtComponent.winmd, 提供接口描述
CppWinrtComponent.dll, 负责接口实现,基于 COM 技术
由于该项目 CppWinrtComponent.vcxproj 默认的平台是 Universal Windows,所以它使用的 VC 运行时函数都是 Store 版本,这导致在非 Universal Windows 应用中会出现找不到 VC 运行时库的异常。为了解决这个问题,针对该类型项目,Visual Studio 2019 version 16.9 版本开始支持属性 Windows Desktop Compatible,设置该属性后所有的 VC 运行时函数会被链接到 Deskotp 版本。

该属性可以在 VS 项目属性面板中配置,对应的 vcxproj 中配置如下:

Copy

true

消费 C++ WinRT 组件
本文主要讨论在如下语言、框架中使用该组件:

C++ Desktop
C++ UWP
.Net Framework Desktop
.Net5 Desktop
C++ Desktop#
使用 VS 的 C++ 项目模板,创建一个空的控制台应用程序 ConsumerCppConsole.vcxproj。

  1. 使用 Nuget 包管理器给该项目安装 Microsoft.Windows.CppWinRT#
    建议安装最新版本,在 Microsoft.Windows.CppWinRT 2.0.200115.8 之后版本中,引入了对 Reg Free 的支持,可以简化 WinRT 组件使用流程,不需要创建额外的 Manifest 文件。

  2. 添加对项目 CppWinrtComponent 生成的 CppWinrtComponent.WinMD 的引用#
    不能直接在 VS 中添加对项目 CppWinrtComponent.vcxproj 的工程引用,但是可以直接添加对文件 CppWinrtComponent.winmd 的引用,在该文件引用的属性中,VS 默认会把"Copy Local" 设置为 True,该操作会导致 CppWinrtComponent.dll 在编译后会被复制到输出目录,这也是期待的行为。

虽然在 VS 的 GUI 中无法直接添加对 CppWinrtComponent.vcxproj 的工程引用,但是可以手动编辑 ConsumerCppConsole.vcxproj 来添加!

Copy

{184b97de-746b-47d4-b055-d18f24b57dba}


3. 使用 Nuget 包管理器给该项目安装 Microsoft.VCRTForwarders.140#
因为 CppWinrtComponent 是用 C++ 代码编写,必不可少会用到 VC 的运行时库,但是默认情况下,CppWinrtComponent.vcxproj 是一个 Universal Windows 的项目,所以它链接的 VC 运行时库都是 Store 版本,Store 版本 VC 运行时库不随 Windows 分发,所以我们的 Desktop 应用在运行时找不到这些 VC 运行时库。

Microsoft.VCRTForwarders.140 的原理是把所有的 Store 版本的 VC 运行时 API 全部链接到 Desktop 版本。组件如其名,就是一个 Forwarder!

如果 CppWinrtComponent.vcxproj 中的 DesktopCompatible 被打开,则此步骤3不再必要。

  1. 调用 CppWinrtComponent 组件#
    CppWinrt.exe 会解析 CppWinrtComponent.winmd 生成头文件 winrt/CppWinrtComponent.h, 通过该头文件,就可以调用组件 CppWinrtComponent 了。

C++/WinRT UWP#
C++/WinRT 有一个 VS 的拓展包,提供了几种基于 C++/WinRT 的项目模板。(https://marketplace.visualstudio.com/items?itemName=CppWinRTTeam.cppwinrt101804264)

用模板创建一个 UWP 项目 ConsumerCppWinrtUWP.vcproj。

  1. 添加对项目 CppWinrtComponent 生成的工程引用#
    因为 ConsumerCppWinrtUWP 和 CppWinrtComponent 都是 Universal Windows 项目,所以可以直接通过 VS 添加对 CppWinrtComponent 的工程引用,CppWinrtComponent 输出的 CppWinrtComponent.winmd 和 CppWinrtComponent.dll 会被复制到 ConsumerCppWinrtUWP 的生成目录。

  2. 调用 CppWinrtComponent 组件#
    CppWinrt.exe 会解析 CppWinrtComponent.winmd 生成头文件 winrt/CppWinrtComponent.h, 通过该头文件,就可以调用组件 CppWinrtComponent 了。

.Net Framework Desktop#
在 VS 里面创建一个 .Net Framework console 项目 ConsumerNetFrameworkConsole.csproj,对于使用 Winrt 组件而言,基于.Net Framework 的 WPF 和 WinFrom 应用与 Console 应用没有任何区别。

值得注意的是,微软在 .Net Framework 4.5引入了对 WinRT 的支持。在 .Net5 中移除了对 WinRT 的原生支持。

  1. 添加对项目 CppWinrtComponent 生成的工程引用#
  2. 创建 Reg Free Manimest 文件#
    C++ WinRT 组件实际是一种进程内(In Process)COM 服务器,使用之前需要向 OS 注册。在 UWP 应用中,Package Manifest 里面可以声明所有用到的 WinRT 组件,在运行时或者安装时,OS 可以根据此文件完成 COM 服务器的注册调用(此处具体细节暂时不清楚,但大致原理应该是这样)。

同样的,针对桌面应用也可以生成一个 manifest 文件,用来描述 WinRT 组件,该文件会被嵌入到桌面应用生成的可执行文件中,在运行时帮助我们完成对 WinRT 组件的加载(COM调用)。

该文件结构如下:

Copy

<?xml version="1.0" encoding="utf-8"?> 可以将该文件任意命名,此处命名为 app.manifest, 然后把它添加到 ConsumerNetFrameworkConsole.csproj 中,为避免出错,选择手动编辑该项目文件,加入如下节点:

Copy

app.manifest

最后编译项目 ConsumerNetFrameworkConsole.csproj,该文件会被嵌入到 ConsumerNetFrameworkConsole.exe 中。所以在分发 ConsumerNetFrameworkConsole.exe 的时候,并不需要将 manifest 文件一起分发。

  1. 使用 Nuget 包管理器给该项目安装 Microsoft.VCRTForwarders.140#
    参考 C++ Desktop 步骤3。

  2. 调用 CppWinrtComponent 组件#
    因为添加了对项目 CppWinrtComponent 的引用,VS 可以从 CppWinrtComponent.winmd 中读取到接口的元数据信息,所以和普通的 .Net 对象一样,可以通过命名空间、类名访问到该 WinRT 组件。

.Net5 Desktop#
在 VS 里面创建一个 .Net5 Console 项目 ConsumerNet5Console.csproj。

微软把 WinRT 的支持从 .Net5 中拿掉后,创建了项目 C#/WinRT, 它包含一个 cswinrt.exe, 可以解析 WinRT 组件的 wimmd 文件并创建相应的 C# 代码,这些代码是关于如果通过 COM 的方式访问 WinRT 组件。这些代码和 C++ Desktop 中 CppWinRT 生成的代码非常一致,几乎就是同一份代码 C# 改写版。实际上 C#/WinRT 和 CppWinRT 是用相同的解析器来解析 winmd 文件的。 详情可参考微软开源项目 xlang。

  1. 创建 .Net5 Library CppWinrtComponentProjection.csproj#
    因为 C#/WinRT 会创建用来访问 WinRT 组件的代码,为了方便使用这些代码,在这儿创建一个单独的 .Net5 Library 来包装这些代码。
    实际上可以略过这一步,直接在项目 ConsumerNet5Console.csproj 上执行以下步骤!

  2. 使用 Nuget 包管理器给 CppWinrtComponentProjection.csproj 安装 Microsoft.Windows.CsWinRT#

  3. 给 CppWinrtComponentProjection.csproj 添加项目 CppWinrtComponent.csproj 的工程引用#
    C#/WinRT 会检查项目 CppWinrtComponentProjection.csproj 依赖的所有 WinRT 组件,并根据步骤4中指定的 WinRT 组件中的命名空间,为其创建C#访问代码。

  4. 添加CsWinRTIncludes#
    C#/WinRT 会读取该项目属性,它指定了引入的 WinRT 组件中的命名空间,这样才能为这个命名空间生成 C# 访问代码。

需要手动在 CppWinrtComponentProjection.csproj 中添加如下节点:

Copy

CppWinrtComponent

5. 编译CppWinrtComponentProjection.csproj#
编译这个 Library, 在该项目 Obj 目录 obj\x64\Debug\net5.0-windows10.0.19041.0\Generated Files\ 会生成如下四个文件:

CppWinrtComponent.cs
WinRT.cs
WinRT_Interop.cs
WinRTEventHelpers.cs
它们就是用来访问 WinRT 组件 CppWinrtComponent 的全部 C# 代码! 同时它们也会被编译成一个 .Net5 Library CppWinrtComponentProjection, 这个 Library 就是所谓的 CppWinrtComponent 的 Projection。

  1. 给ConsumerNet5Console.csproj 添加工程引用 CppWinrtComponentProjection.csproj#
    因为最终需要在 ConsumerNet5Console.csproj 使用 WinRT 组件,所以加入对 projection 项目的引用,该引用是一个标准的 .Net5 Library。

  2. 复制 CppWinrtComponent.dll 到输出项目ConsumerNet5Console的输出目录#
    前6步所作的工作只是用来调用 WinRT 组件,真正的组件服务器是 CppWinrtComponent.Dll,它会在运行时被加载到 ConsumerNet5Console 的进程中。

  3. 使用 Nuget 包管理器给该项目 ConsumerNet5Console.csproj 安装 Microsoft.VCRTForwarders.140#

  4. 调用 CppWinrtComponent 组件#

  5. mosfet驱动芯片https://www.zg886.cn

创建 C++ WinRT 组件相关推荐

  1. 【windows8开发】C++开发WinRT组件和JS调用

    通过Windows Runtime(以下简称WinRT),可以用C++或C#或VB很方便的开发组件(dll),并且这些组件在用Javascript开发的Metro app中可以几乎无缝的被(javas ...

  2. 【Windows8开发】关于WinRT组件,WinRT dll,Win32 dll,WinRT exe组件的一些尝试

    随着Win8的推出,提出了很多新的概念,比如WinRT Component,WinRT dll,WinRT exe component等.基于这些新的概念,进行了很多尝试,本文会把结果分享给大家,希望 ...

  3. react创建组件_如何使用React创建时间轴组件

    react创建组件 These days I've been working on a new page for my website. I wanted to have a Timeline to ...

  4. 【Flutter】Animation 动画 ( AnimatedWidget 动画使用流程 | 创建动画控制器 | 创建动画 | 创建 AnimatedWidget 动画组件 | 动画运行 )

    文章目录 ◯.AnimatedWidget 组件引入 一.创建 AnimatedWidget 动画组件 二.创建动画控制器 三.创建动画 四.动画运行 五.完整代码示例 六.相关资源 Animated ...

  5. 游戏组件——挑战:创建NextBlock游戏组件

    挑战:创建NextBlock游戏组件 本章不是真的讨论NextBlock游戏组件,为此有一个原因.我想你去自己创建它. 在本书的源代码中NextBlock类是空的,你的任务是填充它.NextBlock ...

  6. 创建自定义Tabs组件-01

    创建自定义Tabs组件-01 此文章用于讲解如何封装一个自定义 Tabs 组件.一步一步了解如何封装自己想要的组件. 构思 想象一这个组件该如何使用?一定要站在使用者的角度,大致可能这样. <t ...

  7. 为什么 Cloudera 要创建 Hadoop 安全组件 Sentry ?

    为什么 Cloudera 要创建 Hadoop 安全组件 Sentry ? 1.  大数据的安全体系 要说清楚这个问题,还得从大数据平台安全体系的四个层次说起:外围安全.数据安全.访问安全以及访问行为 ...

  8. CLR via C#:与WinRT组件互操作

    基础知识:如下所示: 1.WinRT组件使用由ECMA协会标准化的.NET元数据格式(ECMA-335)来描述其API,这些元数据会嵌入到扩展名为.winmd的文件中. 2.RCW(运行时可调用包装器 ...

  9. Unity3D之调用WinRT组件

    结论 目前如果想调用WinRT组件引入原生UWP APIs,还是要切换至Universal Windows Platform平台进行调用,在目前版本的Unity(2018.1)的Standalone平 ...

  10. wc 一个进程结果是2_用开放的wc创建一个Web组件

    wc 一个进程结果是2 Previously in this series we covered what Web Components are and some tools used to crea ...

最新文章

  1. pytroch 数据集 datasets DataLoader示例
  2. 输入一个链表,反转链表后,输出新链表的表头(ACM格式)(美团面试题)
  3. 数字图像处理实验(13):PROJECT 05-04,Parametric Wiener Filter
  4. i219v linux,I219V高传播延迟
  5. import cv2找不到模块的解决方法
  6. 修改Sublime Text3左侧导航字号大小及行高
  7. 【强化学习】Actor Critic原理
  8. ubuntu安装配置方法【转】
  9. R语言中读取xlsx文件的方法
  10. C/C++文件字符串处理
  11. (附源码)springboot西安市中小学生护眼平台开发 毕业设计 080855
  12. 误删libcrypto.so.1.0.0
  13. Win10插入U盘无反应,但是U盘是正常的解决方法
  14. bzoj 2827 千山鸟飞绝(treap)
  15. java-net-php-python-springbot学生奖惩管理系统计算机毕业设计程序
  16. 不玩手机的步步高玩大数据:一条短信让你多买一只澳洲大龙虾
  17. 打印预览的线条粗细问题
  18. 京东高层重大调整!首设集团总裁职位,“二号人物”徐雷上位?
  19. 【云原生】AI云开发平台——AI Model Foundry介绍(开发者可免费体验AI训练模型)
  20. 计算机考研【干货满满】:2021武汉理工计算机考研经验分享

热门文章

  1. docker部署homeassistant
  2. mediatek无线网卡驱动 linux,MediaTek 高速USB网卡驱动适配
  3. 外汇风险管理:德鲁克日志之五月十一日
  4. c语言题库字母顺序,C语言题库(带答案)-排版-
  5. 透明网桥的自学习算法
  6. 360全景虚拟现实图片拍摄的注意细节
  7. JAVA中apply方法的原理_关于学习java函数式接口Function中的apply方法的一些感悟
  8. Nature|人类肠道细菌对治疗药物的生物累积
  9. 中国地质大学英语语音学习笔记(六):英语连读——辅音连缀与爆破音读好,让连读更顺畅
  10. embed实现PDF文件预览