客户端使用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这样一个有意思的字符串就比较容易了。下面是是一个使用实例。集合注释很清楚的表示了使用过程。
整个组件的使用过程如代码中所示,很简单。恩,有了饭,还怕不会吃吗,开始还是会怯生,一回生二回熟吧。
现在社会技术的发展也是在被商业用途所驱动着,只要有着广阔的商业前景的技术,其发展必然叙述。
在学习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; }
整个组件的使用过程如代码中所示,很简单。恩,有了饭,还怕不会吃吗,开始还是会怯生,一回生二回熟吧。
相关文章推荐
- Android客户端之“微服私访”App的系统学习(五)使用Picasso实现轮播图以及使用自定义View实现个人中心页面
- 准备整理下自己研究生学习的思路
- ZooKeeper学习笔记-3---ZooKeeper客户端使用
- 工作流引擎Activiti学习---使用流程变量进行个人任务分配
- SVN的学习之路四(客户端工具的使用)
- SVN的学习之路四(客户端工具的使用)
- reids集群学习(二)使用jedis实现redis集群客户端
- restlet2.1 学习笔记(八) 提供接口供客户端使用。
- Git学习个人整理记录(一)
- smartsvn学习(一)Xcode下svn客户端使用指南
- 韩顺平PHP学习视频笔记整理027apache服务器使用及配置② apache目录结构
- 韩顺平PHP学习视频笔记整理028apache服务器使用及配置③ apache虚拟目录
- Android的适配器的学习和使用(整理)
- MySQL学习--使用客户端程序
- windows 重装系统后必装的软件(根据个人使用情况整理,欢迎读者在评论推荐其他好用的软件)
- windows 重装系统后必装的软件(根据个人使用情况整理,欢迎读者在评论推荐其他好用的软件)
- COM组件返回二维数组供javascript和客户端使用
- 一步步学习微软InfoPath2010和SP2010--第二章节--表单需求:使用决策矩阵(6)--结合基于客户端和基于浏览器的控件
- Struts2标签大全,个人整理struts标签全、struts2标签全集学习
- pyhon3模拟登录百度(1)—— 相关学习资料收集及编程思路整理