COM杂谈
Posted threepigs
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了COM杂谈相关的知识,希望对你有一定的参考价值。
由于工作需要,最近开始忙于C#跟COM的交互操作。之前基本上没有玩过C#跟COM,作为一名狂热的技术民工表示,越高级越好玩。即将上市的Windows Phone 7的SDK是基于Silverlight的,用C#作为其编程语言。据我初步的关注了一下,跟Palm的web os有几分神似,主要的应用软件层都是基于Browser。web os比较纯粹,就是Browser上面的html+JS,而WPhone7则是则是通过Silverlight的plugin来嵌入到Browser,殊途同归。他们的一个共同点就是都是managed code,因此彼此都面临着如何调用native的代码。之前做web os开发的时候是利用NPAPI来写插件,通过插件来调用。当然还有ActiveX的方式。WPhone7的Silverlight要调native代码的话,可以用silverlight提供的javascript api,同样用插件的形式,也可以通过COM接口。
COM最好的学习资料莫过于《COM本质》,该讲的都讲了,它比较好的一个方面就是先一步步的介绍为什么要COM,为什么COM是现在这个样子,这样不至于显得太突兀,太死板。与其说COM是一种技术,不如说是一种设计模式,它提供了一种标准式接口来作为软件的复用。学COM就是要用一种软件复用的设计思想来理解。
COM的所有对象都继承自一个标准的接口类 IUnknown,有三个基本接口AddRef, Release, QueryInterface。就是这些标准的接口函数,使得COM的技术可以跨语言,可以用VB,C#来利用C++写的COM对象。前面两个接口函数是引用计数,第三个是重点,它根据一个接口ID来查找获得对应的接口对象。
进程内COM
COM的复用可以分为两种,一是进程内的,通过DLL来提供接口,把该DLL动态加载到需要使用该组件的进程空间内。二是进程外的,通过外部的EXE来提供接口,这种方式需要进程间通信。
进程内的COM是比较灵活的,你可以用很多种方式来加载DLL到进程空间,从而利用该COM DLL提供COM对象。
利用注册表来查找COM DLL: 这种方式是利用windows的一些标准接口来实现。关键词 CoCreateInstance,CoGetClassObject,DllGetClassObject。 下面一步一步的介绍如何利用这些标准的API来生成你的COM对象。写个COM的HelloCom。
HelloComServer:
一. 建一个DLL工程。先定义自己的COM接口
HelloComServer.h
HelloComServer.cpp
二,导出DllGetClassObject接口函数,系统会通过这个接口来生成COM对象,当然得自己实现这个函数。
HelloComServer.cpp
通过一个Module定义文件来把上面这个函数导出,把HelloComServer.def加入工程的linker选项的Input->Module Definition File
HelloComServer.def
三,把该COM DLL写进注册表.
生成下面的 HelloComServer.reg注册表函数(%HelloComServerDLL%为HelloComServer.dll的pathname)
HelloComServer.reg
OK, 一个简单的COM Server Dll就写好了,剩下的就是写一个Client程序来调用这个COM接口了。
HelloComClient.cpp
OK, 一个最简单的COM调用就完成了。注意这里只能用CoGetClassObject,而不能用CoCreateInstance,因为CoCreateInstance是需要用Factory机制来生成COM对象。
CoCreateInstance是先做一次CoGetClassObject(rclsid, dwClsContext, NULL, IID_IClassFactory, &pCF); 得到一个ClassFactory的实例,然后再做一次pCF->CreateInstance(pUnkOuter, riid, ppvObj),来获得对应riid的借口的对象。因此如果你必须要自己实现Factory机制,否则会找不到对应的COM对象。需要对上面的代码做如下改动。
加入ClassFactory实现
HelloComServer.cpp
修改DllGetClassObject导出函数
HelloComServer.cpp
修改之后的代码就可以用CoCreateInstance来创建COM对象了。
以上是关于COM杂谈的主要内容,如果未能解决你的问题,请参考以下文章