当前位置: 首页 > news >正文

windows C++-通过 C++/WinRT 创作 COM 组件(一)

COM组件创建经历了一个渐进的过程,最开始的时候,程序员们可以使用标准的VC编译器创建;后来微软发布了ATL,使得程序员们可以使用ATL快捷的创建com组件,当然现在的winrt也包含对这项经典技术的支持。

默认情况下,C++/WinRT 在 COM 接口方面的表现如何

C++/WinRT 的 winrt::implements 模板是直接或间接派生运行时类和激活工厂的基础。

默认情况下,winrt::implements 会以无提示方式忽略经典 COM 接口。 因此,通过 QueryInterface (QI) 调用经典 COM 接口会失败,并出现 E_NOINTERFACE 错误。 默认情况下,winrt::implements 仅支持 C++/WinRT 接口。

winrt::IUnknown 是一个 C++/WinRT 接口,因此 winrt::implements 支持 winrt::IUnknown 接口 。
winrt::implements 默认情况下不支持 ::IUnknown 本身 。
稍后你将了解如何克服这些默认情况下不支持的情况。 但首先来看看一个代码示例,了解默认情况下会发生什么。

// Sample.idl
namespace MyProject 
{runtimeclass Sample{Sample();void DoWork();}
}// Sample.h
#include "pch.h"
#include <shobjidl.h> // Needed only for this file.namespace winrt::MyProject::implementation
{struct Sample : implements<Sample, IInitializeWithWindow>{IFACEMETHOD(Initialize)(HWND hwnd);void DoWork();}
}

下面是使用 Sample 类的客户端代码。

// Client.cpp
Sample sample; // Construct a Sample object via its projection.// This next line doesn't compile yet.
sample.as<IInitializeWithWindow>()->Initialize(hwnd);
启用经典 COM 支持

好在要让 winrt::implements 支持经典 COM 接口,只需在包括任何 C++/WinRT 头文件之前包括 unknwn.h 标头文件即可。

可以显式这样做,也可以间接这样做,只需包括一些其他的头文件(例如 ole2.h)即可。 一个建议的方法是包括 wil\cppwinrt.h 头文件,该文件是 Windows 实现库 (WIL) 的一部分。 wil\cppwinrt.h 头文件不仅可确保在 winrt/base.h 之前包括 unknwn.h,而且可以让 C++/WinRT 和 WIL 了解彼此的异常和错误代码。

然后,可以对经典 COM 接口调用 as<>,以上示例中的代码将进行编译。

在上面的示例中,即使在客户端(代码使用类)中启用了经典 COM 支持,如果尚未在服务器(代码实现类)中启用经典 COM 支持,则客户端中对 as<> 的调用会失败,因为 IInitializeWithWindow 的 QI 会失败。

局部(非具现)类

局部类在同一编译单元(应用或其他二进制)中实现和使用;因此没有任何具现。下面是仅实现经典 COM 接口的局部类的示例。

struct LocalObject :winrt::implements<LocalObject, IInitializeWithWindow>
{...
};

如果实现该示例,但不启用经典 COM 支持,则下面的代码将失败。 

winrt::make<LocalObject>(); // error: ‘first_interface’: is not a member of ‘winrt::impl::interface_list<>’

同样,IInitializeWithWindow 不会被识别为 COM 接口,因此 C++/WinRT 将忽略它。 对于 LocalObject 示例,忽略 COM 接口的结果意味着 LocalObject 根本没有接口 。 但每个 COM 类必须至少实现一个接口。 

COM 组件的简单示例

下面是使用 C++/WinRT 编写的 COM 组件的简单示例。 这是一个微型应用程序的完整代码清单,因此如果将其粘贴到新 Windows 控制台应用程序 (C++/WinRT) 项目的 pch.h 和 main.cpp 中,则可对其进行试用。 

// pch.h
#pragma once
#include <unknwn.h>
#include <winrt/Windows.Foundation.h>// main.cpp : Defines the entry point for the console application.
#include "pch.h"struct __declspec(uuid("ddc36e02-18ac-47c4-ae17-d420eece2281")) IMyComInterface : ::IUnknown
{virtual HRESULT __stdcall Call() = 0;
};using namespace winrt;
using namespace Windows::Foundation;int main()
{winrt::init_apartment();struct MyCoclass : winrt::implements<MyCoclass, IPersist, IStringable, IMyComInterface>{HRESULT __stdcall Call() noexcept override{return S_OK;}HRESULT __stdcall GetClassID(CLSID* id) noexcept override{*id = IID_IPersist; // Doesn't matter what we return, for this example.return S_OK;}winrt::hstring ToString(){return L"MyCoclass as a string";}};auto mycoclass_instance{ winrt::make<MyCoclass>() };CLSID id{};winrt::check_hresult(mycoclass_instance->GetClassID(&id));winrt::check_hresult(mycoclass_instance.as<IMyComInterface>()->Call());
}

在下一部分,可以看看创建使用 C++/WinRT 实现基本组件类(COM 组件或 COM 类)和类工厂的最小控制台应用程序项目。

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • 【产品那些事】什么是应用程序安全态势管理(ASPM)?
  • cAdvisor+prometheus+grafana搭建监控页面并嵌入自定义页面中
  • 一文掌握直播技术:实时音视频采集、编码、传输与播放
  • 开源AI智能名片商城小程序在私域流量运营中的转化效率与ROI提升研究
  • Ubuntu最小化命令行系统 安装GUI 远程桌面
  • LabVIEW多协议智能流水线控制与监控系统
  • TcpSocket在切后台后如何保活
  • k8s查看容器的日志
  • C#编程中,如何实现一个高效的数据排序算法?
  • redis基本工具类编写
  • GNU/Linux - systemd介绍
  • 实用篇| 如何快速搭建“二手系统”的数据库
  • mac编译opencv 通用架构库的记录
  • Therabody™明星产品TheragunⓇ筋膜枪,以科技健康助力舞台高光时刻
  • JVM上篇:内存与垃圾-回收篇05-本地方法接口和本地方法栈
  • 10个确保微服务与容器安全的最佳实践
  • 2018以太坊智能合约编程语言solidity的最佳IDEs
  • Angular4 模板式表单用法以及验证
  • ESLint简单操作
  • github从入门到放弃(1)
  • go语言学习初探(一)
  • web标准化(下)
  • 前端临床手札——文件上传
  • 前端学习笔记之观察者模式
  • 如何编写一个可升级的智能合约
  • 设计模式走一遍---观察者模式
  • 推荐一个React的管理后台框架
  • 赢得Docker挑战最佳实践
  • 源码之下无秘密 ── 做最好的 Netty 源码分析教程
  • 《TCP IP 详解卷1:协议》阅读笔记 - 第六章
  • SAP CRM里Lead通过工作流自动创建Opportunity的原理讲解 ...
  • ​渐进式Web应用PWA的未来
  • ​决定德拉瓦州地区版图的关键历史事件
  • ​如何在iOS手机上查看应用日志
  • ###51单片机学习(1)-----单片机烧录软件的使用,以及如何建立一个工程项目
  • #Datawhale AI夏令营第4期#AIGC文生图方向复盘
  • #我与Java虚拟机的故事#连载07:我放弃了对JVM的进一步学习
  • (26)4.7 字符函数和字符串函数
  • (6)添加vue-cookie
  • (C语言)输入自定义个数的整数,打印出最大值和最小值
  • (阿里巴巴 dubbo,有数据库,可执行 )dubbo zookeeper spring demo
  • (多级缓存)缓存同步
  • (附源码)spring boot校园拼车微信小程序 毕业设计 091617
  • (论文阅读26/100)Weakly-supervised learning with convolutional neural networks
  • (牛客腾讯思维编程题)编码编码分组打印下标(java 版本+ C版本)
  • (七)Flink Watermark
  • (四)进入MySQL 【事务】
  • (四十一)大数据实战——spark的yarn模式生产环境部署
  • (转贴)用VML开发工作流设计器 UCML.NET工作流管理系统
  • (转载)微软数据挖掘算法:Microsoft 时序算法(5)
  • .NET 3.0 Framework已经被添加到WindowUpdate
  • .NET Framework 3.5中序列化成JSON数据及JSON数据的反序列化,以及jQuery的调用JSON
  • .NET(C#) Internals: as a developer, .net framework in my eyes
  • .netcore如何运行环境安装到Linux服务器
  • .Net环境下的缓存技术介绍