有几件事要清楚:
1、COM接口的实现以DLL形式展现。
2、COM组件在使用前是需要regsvr32.exe注册的。
3、一个COM接口可以对应若干个实现,接口靠IID识别,实现靠CLSID识别。
4、通过CoGetClassObject获得接口指针。
为什么要regsvr32.exe注册COM接口?
注册COM组件,可以理解成是将实现与实现文件绑定的过程。regsvr32.exe在注册表中建立一个从CLSID到DLL的映射,及让引用程序能够通过读取注册表信息知道,CLSID指定的实现类在哪个DLL文件中。
CoGetClassObject函数干了什么?
STDAPI CoGetClassObject(
REFCLSID rclsid,
DWORD dwClsContext,
COSERVERINFO * pServerInfo,
REFIID riid,
LPVOID * ppv);
第一个参数表示希望获得哪个实现类,对后一个参数指向绑定的接口指针,第四个参数说明这个接口指针的类型,第二个和第三个参数说明类对象在哪里被激活(这不是我们关心的重点,暂时忽略)。
在CoGetClassObject函数中,首先通过读取注册表信息,找到rclsid这个实现类对应的DLL(也有可能是.EXE),然后使用LoadLibrary加载动态库。标准COM动态库导出一个全局标准C函数用来创建对象(类似第一章中的CreateFastString函数),利用GetProcAddress函数获得这个函数的地址,这个全局函数利用riid和rclsid询问到一个接口指针,赋值给ppv。
看到CoGetClassObject干的这些事情,我们就知道为什么要注册组件。