您的位置:首页 > 其它

客户端使用COM组件(整理个人学习思路)

2010-07-03 00:53 267 查看
我是属于驱动型的人,无法自主的去做某事。只有等到火烧眉头才知道着急。

现在社会技术的发展也是在被商业用途所驱动着,只要有着广阔的商业前景的技术,其发展必然叙述。

在学习COM技术的时候,也是首先要知道我能够用他来干什么,对我有什么用,才会去学。于是,学习时就要先看看如果给我一个

现成COM组件我该怎么使用它呢。好比,要写游戏就要先玩玩游戏一样了。



于是有了下面的COM组件的使用,也是个人在学习时梳理学习思路:

COM组件其实并不复杂,也就是一个特殊的DLL而已。但是一般的DLL我们只要知道它导出了哪些函数。我们该怎样调用即可。

而COM组件,我们的目的不是使用它导出的函数,而是要利用它来实现某个具体的功能。

一般来说,COM组件的DLL导出的函数一般有

DllCanUnloadNow
DllGetClassObject
DllRegisterServer

DllUnregisterServer

函数。当然不是必须的。其中DllRegisterServer和DllUnregisterServer是用来将COM组件注册到系统中。至于其他的函数以后学

习中在说。既然是说COM组件在客户端的使用。就开始了。

首先。COM组件在注册表中注册,就是把组件的代号写在注册表中。该代号就是在写组件时给定的。然后注册时就是告诉系统该代号对应的组件在系统中的什么位置,以及该组件名称是什么。比如在我的系统中有一个组件是COM.dll,在编写主键的时候已确定其

GUID是54BF6563-1007-11D1-B0AA-444553540000,组件名是server.object.在使用Regsvr32 COM.dll注册后,就会在

HKEY_LOCAL_MACHINE/SOFTWARE/Classes/CLSID/下生成一子项为:{54BF6563-1007-11D1-B0AA-444553540000},该子项下又对应两个子项:InProcServer32和ProgID通过注册表导出得到该组件注册后注册表信息为:

[HKEY_LOCAL_MACHINE/SOFTWARE/Classes/CLSID/{54BF6563-1007-11D1-B0AA-444553540000}]
@="server.object"

[HKEY_LOCAL_MACHINE/SOFTWARE/Classes/CLSID/{54BF6563-1007-11D1-B0AA-444553540000}/InProcServer32]
@="E://PROGRA~1//MICROS~1//MYPROJ~1//COM//Debug//com.dll"

[HKEY_LOCAL_MACHINE/SOFTWARE/Classes/CLSID/{54BF6563-1007-11D1-B0AA-444553540000}/ProgID]
@="server.object"



注册后的组件就可以被客户端使用了。在程序代码中。要使用COM组件。首先调用CoInitialize()函数进行初始化COM库工作。

与其对应的是在使用完成后调用CoUninitialize()清理COM环境。

一般来说,组件的{54BF6563-1007-11D1-B0AA-444553540000}是唯一的。可以直接使用它来创建组件实例,查找组件接口。但是由于该值不容易记忆。一般使用其ProgID值来间接查找。其中通过函数CLSIDFromProgID 来转换。记忆ProgID这样一个有意思的字符串就比较容易了。下面是是一个使用实例。集合注释很清楚的表示了使用过程。
int main()
{
	HRESULT hResult = 0;
	IUnknown *pUnknown;
	ITestInterFace* pTestCom;//接口指针
	if (CoInitialize(NULL) != S_OK) //初始化COM库
		printf("Initialize COM library failed!/n");
		return -1;
	}
	
	GUID TestComCLSID;//组件标识ID,全球唯一,在注册表中可以直接查找到
         //TestCom.Object是注册表中的ProgID的值,通过它就可以查找到组件的标识ID
	hResult = ::CLSIDFromProgID(L"TestCom.Object", &TestComCLSID);
	if (hResult != S_OK) 
	{
		printf("Can't find the TestCom CLSID!/n");
		return -2;
	}
        //通过组件标识ID创建一个组件实例,pUnknown返回组件的一个通用接口,通过它
         //可以查询我们想要的接口
         //CLSTX_INPROC_SERVER表示是进程类主键
         //其实此处也通过InProcServer32查找到组件的路径并加载到内存
	hResult = CoCreateInstance(TestComCLSID, NULL, 
		CLSCTX_INPROC_SERVER, IID_IUnknown, (void **)&pUnknown);
	if (hResult != S_OK) 
	{
		printf("Create object failed!/n");
		return -2;
	}
        //查找要使用的接口,IDD_TestCom是组件的标识符,通过该标识符也就查找到对应的接口了
         //该标识符由服务端组件告知,否则写的组件也就失去其意义。
	hResult = pUnknown->QueryInterface(IID_TestCom, (void **)&pTestCom);
	if (hResult != S_OK) {
		pUnknown->Release();
		printf("QueryInterface ITestInterFace failed!/n");
		return -3;
	}
        //查找到接口后调用接口提供的功能
	pTestCom->TestCom();
        //告诉接口,不在使用
	pTestCom->Release();

        //判断该接口是否还被使用
	if (pUnknown->Release() == 0)
	{
		printf("Com Free Succeeded!/n");
	}
        //清理环境
	CoUninitialize();
	return 0;
}


整个组件的使用过程如代码中所示,很简单。恩,有了饭,还怕不会吃吗,开始还是会怯生,一回生二回熟吧。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐