COM技术入门(3)

2023-01-31 05:01:00 技术 入门

(1)COM组件注册卸载与智能指针


一COM组件注册和卸载

1.Regsvr32.exe命令是用来对"Active控件"进行注册的

命令格式

注册 Regsvr32 路径/名称.dll  

卸载  Regsvr32 /u 路径/名称.dll

2.ATL制作出的简单对象是".dll"形式

Visual Stduio在编译成这个dll时,对它自动进行了注册.


blob.png

比如我注册一个

blob.png

就成功注册啦, 卸载只要在前面加个 /u就行

blob.png

如果你卸载了程序就用不了这个组件了,因为注册表找不到相关信息.



3.注册好后查看.打开注册表 reg就是注册检测 Edit就是编辑

RegEdit即可打开注册表



4.在HKEY_CALSSES_ROOT\CLSID\搜索组件的clsid

blob.png


InprocServer32 放了DLL文件所在地址

blob.png


ProgID 简称 COM组件的PropID

表示组件

blob.png


5.COM组件注册意义

注册表信息中记录了组件的CLSID,组件的路劲,组件的PropID等

COM组件是跨应用的,网页,MFC,C# VB这些需要识别并创建我们的组件,最终

得到组件路劲,而路劲是可能改变的,比如用户安装程序时选择不同目录,CLSID

跟PropID是不变的,我们采用CLSID或PropID去创建组件,不管COM组件的DLL在哪个位置

 从vista开始,注册需要权限,




二、智能指针

1.简介

c++在调用COM接口指针是很危险的,因为程序每一处使用都

严格并且正确的调用AddRef()与Release()方法,一旦出现问题,就会造成

对象不能被释放,或者对象被重复删除

所以C++程序员使用COM接口时,得小心翼翼的,

改变这种现状的方法: 让变成更简单

使用智能指针即可.


2.CComPtr是智能指针,是ATL提供的一个模板类

能封装COM接口的AddRef()与Release()方法

CComPtr声明出的变量,是一个对象,这个对象封装了COM

接口指针,这个对象的使用访问跟COM接口的使用几乎一样.



3.智能指针与使用

	HRESULT hr = E_FaiL;
	hr = CoInitialize(NULL);
	if(SUCCEEDED(hr))
	{
		//智能指针
		CComPtr<IHelloSimpleObject>spHello;
		//创建实例 指定的类标识符创建一个Com对象
		//COM类其实就是组件,COM类标识 就是组件标识
		hr = spHello.CoCreateInstance(CLSID_HelloSimpleObject);
		//如果不使用智能指针则要这样
		//hr = CoCreateInstance(CLSID_HelloSimpleObject,NULL,CLSCTX_INPROC_SERVER,
		//	IID_IHelloSimpleObject,(LPVOID*)&pHello);

		if(SUCCEEDED(hr))
		{
			//接口的方法测试
			LONG sum = 0;
			hr = spHello->SumLong(100,100,&sum);

			//读取描述
			BSTR bstrs = SysAllocString(L"");
			hr = spHello->get_m_desc(&bstrs);
			SysAllocString(bstrs);
			bstrs = NULL;

			//写入
			BSTR strb = SysAllocString(L"MFC中测试");
			hr = spHello->put_m_desc(strb);
			SysAllocString(strb);
			bstrs = NULL;

			bstrs = SysAllocString(L"");
			hr = spHello->get_m_desc(&bstrs);
			SysAllocString(bstrs);
			bstrs = NULL;
		}
		//这里则可以省略 不用调用
		//spHello->Release();
	}

	CoUninitialize();



4.智能指针的使用方式与COM接口指针方法相似,也有区别

智能指针创建对象时,内部有一个智能指针.其实他是一个类对象

是一个模板的,

创建好后,这个对象对象内部有一个IHelloSimpleObjet,初始化NULL

IHelloSimpleObject* pIhello,  一个原始的COM接口指针。


5.这两个在CoCreateInstance中使用方法一模一样,因为对智能指针的&材质

会转变成对智能指针内部的 IHelloSimpleObjedt(其实是个模板变量)进行&操作


6.二者使用->操作用法意义一样,因为智能指针的->会转变成

_NoAddRefReleaseOnCComptr<IHelloSimpleObjectSub>*接口变量->操作

_NoAddRefReleaseOnCComptr<IHelloSimpleObjectSub>是IHelloSimpleObjectSub的子类


7.智能指针把AddRef()与Release()放在 private里,所以你不能手动调用。


8.对COM接口指针的赋值是需要AddRef操作,智能指针则不需要,他会智能的执行.

Release也是智能的,不需要我们去管理了.


9.智能指正的变量是一个对象

如果是局部变量,将这个局部变量声明器结束时,执行智能指针西沟

如果是成员变量,在成员所在类对象析构时,执行智能指针的析构

如果是静态变量.将在程序结束时,执行智能指针的析构


三、智能指针注意点

1如果要使用一个智能指针,直接给它赋值NULL,这样内部COM接口指针

也会执行Release操作,来减少引用计数.


2.当对指取地址时(&)要确保智能指针为NULL,因为他返回的是内部的

COM接口指针,如果不为NULL则旧的COM接口指针,将没有执行Release而

赋值了一个新的COM指针接口.


3.不过可以放心,因为这时候,智能指针不为NULL,智能指针

代码通过assert报错,







相关文章