那个牌子产妇卫生巾好:CoCreateInstance 和 CoGetObject

来源:百度文库 编辑:九乡新闻网 时间:2024/05/05 04:27:30
我也搞了很久没太懂,把自己的理解成果跟楼主分享一下

先说下几种标识:
ProgID:表示COM对象的字符串,后面可以跟版本号,不跟版本号就用安装的最高版本(如“Word.Application.8”)
CLSID:表示COM对象的GUID,在注册表中ProgID和CLSID有对应的,ProgID为了看起来方便而已,ProgID最终要转成CLSID来使用
IID:表示接口的GUID,唯一标识一个接口类型

所以ProgID或CLSID表示一个COM对象的类型,它可以实现多个IID表示的接口
而某个IID表示的接口也可以被多个不同CLSID标识的COM对象来实现

STDAPI CoGetClassObject(
REFCLSID rclsid, //COM对象的CLSID
WORD dwClsContext, //COM对象的运行环境(进程内、进程外、远程)
COSERVERINFO* pServerInfo, //远程的服务器信息(机器名、IP等)
REFIID riid, //返回接口的IID,这儿只能是IID_IClassFactory或IID_IClassFactory2
LPVOID* ppv //返回的类厂接口
);
CoGetClassObject是COM库提供的方法,目的是获取COM组件的类工厂,为什么要搞类工厂这个东西而不是直接导出一个叫CreateObject之类的函数呢,我猜想是出于跨语言考虑的,譬如:在某个脚本语言中,它并不支持Dll导出函数的调用,但它支持COM,说不定它可以从某种途径(不一定是dll导出函数的调用)拿到某个起始接口(如:IClassFactory),那么它就可以创建COM对象,然后使用它了,这样可以降低对导出函数的依赖性。

后来微软发现大部分支持DLL调用的高级语言都调用导出函数CoGetClassObject来创建工厂,然后再创建COM对象显得比较烦琐,于是有了CoCreateInstance这个方法了。
STDAPI CoCreateInstance(
REFCLSID rclsid, //COM对象的CLSID
LPUNKNOWN pUnkOuter, //如果该COM对象支持聚合,并且你要把它聚合到你的对象内,请把你的对象的IUnkown接口传递给它
DWORD dwClsContext, //COM对象的运行环境(进程内、进程外、远程)
REFIID riid, //COM对象的接口的IID(不是类工厂接口)
LPVOID* ppv //返回的COM对象接口
);
CoCreateInstance也是COM库提供的方法,它其实就是现调用CoGetClassObject来拿到类工厂,然后调用类工厂来创建COM对象。

WINOLEAPI CoGetObject(
LPCWSTR pszName, //COM对象的ProgID
BIND_OPTS* pBindOptions, //绑定选项,具体看MSDN
REFIID riid, //COM对象的接口的IID(不是类工厂接口)
void** ppv //返回的COM对象接口
);
CoGetObject也是COM库提供的,它是用命名绑定技术来创建COM对象,可以直接用ProgID来创建或者获得COM对象。
与CoCreateInstance不同的是,由于它使用的名字绑定技术,它会先查询ROT(运行时对象表),如果该COM组件(如Word.Application)往ROT进行注册的话,它可以查到已经创建的COM对象并返回给你,而CoCreateInstance仍然会创建新的COM对象返回给你。