组件的创建和类厂
只针对进程内组件。
进程内组件一般使用DLL来实现,实现组件的DLL要导出以下四个函数:
DllGetClassObject
DllCanUnloadNow
DllRegisterServer
DllUnregisterServer
这些函数需要组件的实现者来实现并从DLL中导出。
++++++++++++++++++++++++++++++++++++++
组件的创建
函数DllGetClassObject和组件的创建紧密相关。在COM库中有三个函数可以创建对象(获得某个接口):
CoGetClassObject
CoCreateInstance
CoCreateInstanceEx
首先关注函数CoGetClassObject ,它的函数原型是:
STDAPI CoGetClassObject(
REFCLSID rclsid,
DWORD dwClsContext,
COSERVERINFO * pServerInfo,
REFIID riid,
LPVOID * ppv
);
参数说明:
rclsid:class-id,指定了COM类的唯一标识。
dwClsContext:可执行代码的运行上下文。
pServerInfo:被用在DCOM中,一般设为NULL
riid: 通常情况下是接口IClassFactory的标识符IID_IClassFactor。如果类厂对象还支持IClassFactory2接口,也可以是接口IClassFactory2的标识符。
ppv:用来存放获得的接口指针。
对于进程内组件,CoGetClassObject 调用DLL中的导出(export)函数DllGetClassObject,并将参数rclsid,riid和ppv传递给函数DllGetClassObject。函数DllGetClassObject创建类厂对象,并将类厂对象接口通过参数ppv返回。
函数CoCreateInstance 是一个辅助函数,实际上该函数内部调用了CoGetClassObject 。该函数的参数rclsid,dwClsContext,riid,ppv含义与函数CoGetClassObject 的对应参数含义是一样。参数pUnkOuter与类厂接口的函数CreateInstance的相应参数是一致,主要被用在对象被聚合的情形。
STDAPI CoCreateInstance(
REFCLSID rclsid,
LPUNKNOWN pUnkOuter,
DWORD dwClsContext,
REFIID riid,
LPVOID * ppv
);
函数CoCreateInstance将得到类厂,然后使用类厂得到接口指针的过程封装起来了。在参数ppv获得的接口指针就是riid对应的接口指针。函数CoCreateInstance的实现步骤一般是:
a 得到类厂接口的指针
b 创建COM对象,返回由riid标识的接口指针。
由于CoCreateInstance不能创建远程机器上的对象,所以COM库又提供了函数CoCreateInstanceEx。
HRESULT CoCreateInstanceEx(
REFCLSID rclsid,
IUnknown * punkOuter,
DWORD dwClsCtx,
COSER