COM技术入门(3)

发布时间:2019-09-06 08:52:01编辑:auto阅读(1428)

    (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报错,







关键字