广告
返回顶部
首页 > 资讯 > 后端开发 > 其他教程 >C++ com编程学习详解
  • 856
分享到

C++ com编程学习详解

2024-04-02 19:04:59 856人浏览 泡泡鱼
摘要

目录COM简介COM 规范首先创建一个ATL工程,创建后你会看到一个idl文件COM 原理学习ActiveX总结COM简介 COM全程为component object model

COM简介

COM全程为component object model ,是一个二进制标准可以用于跨语言调用dll模块或者实现组件化以及复用。com不仅可以用在单个操作系统也可以用在跨服务上,在很多大型软件如wps,office你都会看到它的身影。

比如java中调用规范如下:

JAVA COM编程

你可能会在电脑出现缺少dll情况,一种修复方式下载dll然后调用regsvr32.exe xxx.dll即可修复。

在这里插入图片描述

上面便是COM组件的注册,本质是把这个dll信息注册到注册表中,以便其他系统软件可以加载。

Flutter也提供相关接口封装flutter相关文档链接

本文主要介绍c++下使用com规范编程。

为什么需要COM?仅仅是为调用dll何必引用一个如此复杂的概念?

1.假设某个exe升级其中一个dll想要仅发布dll而不是是发布主体文件,在大多数情况下是没有任何问题的。但是在不同编译器编译(或者同编译器不同版本)出的主体exe和dll是有可能出现内存布局上的差异引起的奔溃。startoverflow上的一个经典问题

2.跨语言调用,比如C语言以\0结束,但是不是所有语言字符串定义都是如此。

3.跨进程或者跨服务上调度dll函数

4.dll代码复用 与共享

COM 规范

com使用idl文件去定义dll函数或者接口,之后用midl编译器生产对应的头文件,开发者再利用其去实现接口。

接口有自己的标识符号IID 防止与其他人的接口在名字上冲突.

在这里插入图片描述

编译后的某个头文件你会看到IID_XXXXX 如下所示

在这里插入图片描述

如果说IID是为了标识一个接口,那么应该还有一个ID去用于标识实现类,这个实现类的id我们称为CLSID,CLSID会在注册表映射一个dll信息,也就是我们可以用个这个CLSID可以在注册表中寻找到dll文件信息。

s在这里插入图片描述

tip:一个实现类可能会包含多个接口

更多idl语法可以参阅官方指南:

https://docs.microsoft.com/en-us/windows/win32/com/defining-com-interfaces

Https://bbs.csdn.net/topics/30094944?list=34484

使用ATL编写一个com共享dll库 使用管理员权限运行vs(编译dll会自动调用regsvr32注册到注册表,但是需要权限)

首先创建一个ATL工程,创建后你会看到一个idl文件

在这里插入图片描述

新建一个接口如下:

在这里插入图片描述

在这里插入图片描述

上面ProgId一个可选项,它的作用是提供了另一种方式寻找注册过的dll。

在这里插入图片描述

完成后我们的IDL会自动产生相关语法到文件中

s在这里插入图片描述

同时会创建对应的头文件和c文件如下

在这里插入图片描述

此时我们到类视图添加一个接口方法

在这里插入图片描述

添加后idl同样会如下图所示生产对应的语法

在这里插入图片描述

对应的c文件自行实现接口(最后一个参数作为返回参数)

在这里插入图片描述

编译后会产生 工程名_i.c和工程名.h文件,并且自动会将dll注册注册表中。

将上诉两个文件拷贝其他使用工程中(注意我们并没有拷贝dll)如下图所示:

在这里插入图片描述

然后再调代码如下所示调用:


#include <iOStream>
#include"FMYALTFOUR_i.h"
int main()
{
	//初始化
	CoInitialize(NULL);
	IClassFactory *pFactory = NULL;
	//通过CLSID从注册表中查到dll位置并加载 然后返回一个类工厂
	HRESULT hr = CoGetClassObject(CLSID_IfmyMathHelper,CLSCTX_INPROC_SERVER,
		NULL,
		IID_IClassFactory, (void**)&pFactory
		);
	//利用类工厂得到一个接口实例化对象
	IIfmyMathHelper * pSuperMath = NULL;
	pFactory->CreateInstance(NULL, IID_IIfmyMathHelper, (void**)&pSuperMath);
	long ret;
	pSuperMath->add(1, 2, &ret);
	//反初始化
	CoUninitialize();
}

当然这是其中一种调用方式,还有一种是预留给vb这类语言调用的实现这种方式你不需要拷贝上诉两个文件,但是创建接口必须勾选接口双重。


int main()
{
	//初始化
	CoInitialize(NULL);
	HRESULT hr;
	GUID clsid;
	IUnknown FAR* punk;
	IDispatch FAR* pdisp = (IDispatch FAR*)NULL;
	//通过progId反向查找出clsid 去加载dll
	hr = CLSIDFromProgID(OLESTR("progIdfmyMathHelper.1"), &clsid);
	IDispatch* pDispatch = NULL;
	hr = CoCreateInstance(clsid, NULL, CLSCTX_INPROC_SERVER, IID_IDispatch, (void**)&pDispatch);
	LPOLESTR szMember[1] = { (LPOLESTR)OLESTR("add") };
	DISPID dipid[1] = { 0 };
	hr=pDispatch->GetIDsOfNames(IID_NULL, szMember, 1, LOCALE_USER_DEFAULT, dipid);
	CComVariant vars[2];
	DISPPARAMS args = { NULL,NULL,0,0 };
	vars[0] = 2;
	vars[1] = 1;
	args.cArgs = 2;
	args.rgvarg = vars;
	CComVariant Ret;
	hr=pDispatch->Invoke(dipid[0], IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_METHOD,
		&args, &Ret,NULL,NULL
		);
	std::cout << "Hello World!\n" << Ret.lVal;
	//反初始化
	CoUninitialize();
}

COM 原理学习

regsvr32.exe xxx.dll 本质作用会加载dll然后调用如下几个函数,dll应该根据规范在对应函数中实现对应的逻辑(比如DllReGISterServer中应当实现注册信息到注册表中)

在这里插入图片描述

上面几个函数在你创建atl工程的def文件可以看到.

我们接下来看看注册表中的信息,dll首先会利用CLSID的数值在如下注册表路径创建对应的信息
计算机\HKEY_CLASSES_ROOT\WOW6432node\CLSID\{xxxxxxxxxxx}

在这里插入图片描述

在这里插入图片描述

如果ProgId会在如下图位置创建额外的信息,主要用于提供其他方式寻找到dll信息。

在这里插入图片描述

其中32位系统和64系统可能路径有所不同可以参考如下链接所示

How to use the Regsvr32 tool and troubleshoot Regsvr32 error messages

自己模拟atl的实现代码: https://GitHub.com/Zjvngvn/studyCom.git

ActiveX

ActiveX也是基于Com实现的一个UI组件库。你可以在ATL下轻松的创建对应控件,然后在其他工程插入即可

在这里插入图片描述

总结

本篇文章就到这里了,希望能够给你带来帮助,也希望您能够多多关注编程网的更多内容!

--结束END--

本文标题: C++ com编程学习详解

本文链接: https://www.lsjlt.com/news/136389.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • C++ com编程学习详解
    目录COM简介COM 规范首先创建一个ATL工程,创建后你会看到一个idl文件COM 原理学习ActiveX总结COM简介 COM全程为component object model ...
    99+
    2022-11-12
  • C++学习之线程详解
    目录开篇线程的状态多线程的构建计算时间一、程序运行时间二、chrono共享资源和互斥锁condition_variable线程池总结开篇 多线程是开发中必不可少的,往往我们需要多个任...
    99+
    2022-11-12
  • C++指针学习详解
    目录指针的基本概念一、指针变量的定义和使用二、指针所占的空间内存1.空指针 野指针2. const修饰指针利用指针访问数组中的每个元素.总结指针的基本概念 指针的作用:可以通过指针间...
    99+
    2022-11-12
  • Android编程之SurfaceView学习示例详解
    本文实例讲述了Android编程之SurfaceView学习示例。分享给大家供大家参考,具体如下: SurfaceView是View的子类,使用的方式与任何View所派生的类都...
    99+
    2022-06-06
    示例 surfaceview Android
  • C/C++ 线程超详细讲解(系统性学习day10)
    目录 前言 一、线程基础 1.概念  2.一个进程中多个线程特征 2.1 线程共有资源 2.2 线程私有资源   3.线程相关的api函数  3.1 创建线程 创建线程实例代码如下:  需要特别注意的是: -lpthread和-pthre...
    99+
    2023-10-18
    学习 c语言 c# 开发语言
  • C++11学习之多线程的支持详解
    目录C++11中的多线程的支持1.C++11中的原子类型1.1 原子类型的接口1.2简单自旋锁的实现2.提高并行程度2.1 memory_order的参数2.2 release-ac...
    99+
    2023-02-06
    C++11多线程支持 C++11多线程
  • C/C++进程超详细详解【中部分】(系统性学习day07)
    目录 前言 一、守护进程 1.概念 2.守护进程创建的原理(如图清晰可见)  3.守护进程的实现(代码块) 二、dup和dup2 1,复制文件描述符 2.文件描述符重定向 三、系统日志 1,打开日志 2,向日志中写消息 3,关闭日志 四,...
    99+
    2023-10-05
    学习 c语言 c# 开发语言
  • Python学习之面向对象编程详解
    目录什么是面向对象编程(类)类的关键字 - class类的定义与使用类的参数 - selfself 的解析与总结类的构造函数构造函数的创建方法关于对象的生命周期什么是面向对象编程(类...
    99+
    2022-11-13
  • C# CLR学习 C++使用namespace实例详解
    目录一:背景二:聊一聊 namespace1. 简单的隔离2. 使用 using 导入3. 使用 using 定义别名4. 使用 using namespace 导入一:背景 相信大...
    99+
    2022-11-13
  • 详解c++良好的编程习惯与编程要点
    目录1、以良好的方式编写C++ classHeader(头文件)中的防卫式声明把数据放在private声明下,提供接口访问数据不会改变类属性(数据成员)的成员函数,全部加上const...
    99+
    2022-11-12
  • C++学习之命名空间详解
    目录1.命名空间的定义和使用2.命名空间嵌套3.命名空间别名4.标准命名空间总结C++中,命名空间(namespace)是一个重要的概念。命名空间可以为函数、变量、类等定义作用域,以...
    99+
    2023-05-18
    C++命名空间定义 C++命名空间使用 C++命名空间
  • C++学习之异常机制详解
    目录1. 异常处理机制介绍2. 如何抛出异常和捕获异常2.1 抛出异常2.2 捕获异常3. 如何实现自己的异常4. 注意事项5. 面试常问的题目6. 答案7. 总结1. 异常处理机制...
    99+
    2023-05-15
    C++异常机制 C++异常
  • 详解Spring学习之编程式事务管理
    前言在前面的内容,基本已经学习了事务的基本概念以及事务隔离级别等,接下来的几个小节,将学习怎么使用Spring进行事务管理,在Spring中,对事务进行管理有多种方法,主要分别编程式和声明式,本小节主要学习编程式事务管理,后面讲学习Spri...
    99+
    2023-05-31
    spring 编程式 事务
  • C++学习之指针的使用详解
    C++中指针储存一个地址 声明: datatype* p;  datatype表示指针指向的数据类型。 int num=0; int* pnum=&num; //&...
    99+
    2023-03-02
    C++指针使用 C++指针
  • C++EasyX学习之鼠标操作详解
    目录基础代码进阶编程基础代码 功能:移动画点,左键画方块,右键退出。  #include <graphics.h> #include <conio.h&...
    99+
    2022-11-13
  • C++学习之初始化列表详解
    目录前言一、类的初始化表二、initializer_list前言 本文主要介绍C++中地初始化列表 目前对初始化列表应该有两个方面的定义,一个是类的构造函数中使用的那个初始化表,另一...
    99+
    2023-03-19
    C++初始化列表 C++ 列表
  • C++学习之多态的使用详解
    目录前言多态向上转型向下转型作用域前言 最近为了完成数据库系统的实验,又复习起了《C++ Primer》,上一次看这本巨著也是大二下的六月份,那时看面向对象程序编程这一章还云里雾里的...
    99+
    2022-11-13
  • 详解JUC并发编程中的进程与线程学习
    目录进程与线程进程线程同步异步串行并行执行时间创建和运行线程Thread 与 Runnable 的关系原理分析查看进程线程运行原理线程上下文切换start与run方法sleep方法s...
    99+
    2022-11-13
  • C/C++网络编程基础知识超详细讲解上部分(系统性学习day11)
    目录 前言 一、网络的含义与构成 含义: 构成:  二、网络的体系结构 1>OSI七层模型 2>TCP/IP协议体系结构  3>数据经过体系结构,怎么封装  4>端口号 5>大小端序 6>TCP/UDP传输层的协议  三、系统函数API学...
    99+
    2023-10-21
    网络 学习 c语言 c# 开发语言
  • C#CLR中学习C++关键词extern使用详解
    目录一:背景extern1. 变量定义和变量引用2. extern "C"一:背景 在 CLR 源码中有很多的 extern 和 e...
    99+
    2022-11-13
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作