Inside COM读书笔记-----类厂
来源:互联网 发布:linux查询文件大小 编辑:程序博客网 时间:2024/06/06 22:14
1.CoCreateInstance
通过传人参数CLSID创建相应组件的一个实例,并返回此组件实例的某个接口。
- CoCreateInstance的声明
HRESULT __stdcall CoCreateInstance(
__in REFCLSID rclsid,
__in_opt LPUNKNOWN pUnkOuter,
__in DWORD dwClsContext,
__in REFIID riid,
__deref_out LPVOID FAR* ppv
);
有四个输入参数和一个输出参数,第一个参数待创建组件的CLSID,第二个参数用于聚合组件,第三个参数是限定所创建组件的执行上下文。第三个参数组件上待使用的接口IID,最后一个参数返回接口的指针。
- CoCreateInstance的使用
//Create Component
IX *pIX = NULL;
HRESULT hr = CoCreateInstance(CLSID_Component,
NULL,
CLSCTX_INPROC_SERVER,
IID_IX,
( void**)&pIX);
if(SUCCEEDED(hr))
{
pIX->Fx();
pIX->Release();
}
类上下文
CoCreatInstance第三个参数dwClsContext可以控制所创建的组件是在与客户相同的进程中允许,还是在不同的进程中运行,或者是子啊远程机器上运行。
客户可以在三种不同的上下文中使用某个组件:进程中、本地以及远程。常用组合定义:
2.类厂
CoCreateInstance实际上并没有直接创建COM组件,而是创建一个被称作类厂的组件,再由类厂创建组件,起唯一功能呢就是创建其他的组件。精确的说是某个特定的类厂将创建只同某个特定的CLSID相应的组件。客户可以通过类厂所支持的接口来对类厂创建组件的过程加以控制。创建组件的标准接口是
IClassFactory。
IClassFactory。
CoGetClassObject
CoCreate接收一个CLSID作为参数并返回指向所创建的组件中的某个接口指针。为创建同某个组件想对应的类厂,需要CoGetClassObject函数。
HRESULT __stdcall CoGetClassObject(
__in REFCLSID rclsid,
__in DWORD dwClsContext,
__in_opt LPVOID pvReserved,
__in REFIID riid,
__deref_out LPVOID FAR* ppv);
参数和CoCreateInstance很相似。第一个参数都是组件的CLSID.第二个参数则是创建组件的执行上下文。最后两个参数也想同,CoGetClassObject返回的是指向类厂中某个接口的指针。而CoCreateInstance是返回的指向组件中某个接口的指针。其中pServerInfo指针将被DCOM用于控制对远程组件的访问。
ICalssFactory
IClassFactory : public IUnknown
{
public:
virtual /* [local] */ HRESULT STDMETHODCALLTYPE CreateInstance(
/* [unique][in] */ IUnknown *pUnkOuter,
/* [in] */ REFIID riid,
/* [iid_is][out] */ void **ppvObject) = 0;
virtual /* [local] */ HRESULT STDMETHODCALLTYPE LockServer(
/* [in] */ BOOL fLock) = 0;
};
CoCreateInstance与CoGetClassObject的比较
在每次创建组件时,先创建相应的类厂,然后获取IClassFactory指针来创建所需接口比直接调用CoCreateInstance来创建所需的组件要复杂。看下如何用CoGetClassObject实现CoCreateInstance:
HRESULT __stdcall CoCreateInstance(
__in REFCLSID rclsid,
__in_opt LPUNKNOWN pUnkOuter,
__in DWORD dwClsContext,
__in REFIID riid,
__deref_out LPVOID FAR* ppv)
{
*ppv = NULL;
IClassFactory *pIFactory = NULL;
HRESULT hr = CoGetClassObject(rclsid,
dwClsContext,
NULL,
IID_IClassFactory,
( void**)&pIFactory);
if (SUCCEEDED(hr))
{
hr = pIFactory->CreateInstance(pUnkOuter, riid,ppv);
pIFactory->Release();
}
}
可以看到CoCreateInstance首先调用CoGetClassObject来获取类厂中的ICalssFactory接口指针,再通过ICalssFactory::CreateInstance完成新组件的创建。
3.类厂的实现
DllGetClassObject的使用
CoGetClassObject需要DLL中的一个特定函数来创建组件的类厂。此函数就是DllGetClassObject。
HRESULT __stdcall DllGetClassObject(
__in REFCLSID rclsid,
__in REFIID riid,
__deref_out LPVOID FAR* ppv
);
这三个参数和CoGetClassObject的三个参数是相同的,将CLSID传给DllGetClassObject可以是DLL支持任意数目的组件,DllGetClassObject可以用CLSID来选择合适的类厂。
组件的创建过程
首先客户通过CoGetClassObject来启动组件的创建过程。其次是Com库他实现了CoGetClassObject函数,第三是DLL,其中实现了被CoGetClassObject叼哦那个的DllGetClassObject函数,DllGetClassObject函数的任务就是创建客户所请求的类厂。创建玩类厂后客户将使用ICalssFactory接口来创建相应的组件。
4.同一DLL中的多个组件
将待创建的组件CLSID传给DllGetClassObject来创建相应的类厂。
5.DLL的卸载
COM库实现了一个名为CoFreeUnusedLibraries函数以释放哪些不在使用的库,但何时不再使用库呢?CoFreeUnusedLibraries将调用DllCanUnloadNew以询问DLL是否可以被卸载。LockServer给客户提供了一种将服务器保存在内存中,直到使用完毕的方法,客户需要调用LockServer(True)锁住服务器。使用完毕后就可以使用LockServer(False)解锁。
- Inside COM读书笔记-----类厂
- Inside COM读书笔记------接口
- Inside COM读书笔记-----多线程
- Inside COM读书笔记------QueryInterface接口
- Inside COM读书笔记------引用计数
- Inside COM读书笔记------动态链接库
- Inside COM读书笔记-----包容和聚合
- Inside COM读书笔记-----ExE中的服务器
- Inside COM读书笔记-----调度接口与自动化
- Inside COM读书笔记-----关于HRESULT、GUID、注册表及其它细节
- COM ---- Inside COM Note
- Inside COM Object Model
- Inside c++ object model 读书笔记
- 读书笔记《inside mysql:sql programming》
- Inside COM 学习笔记三
- Inside COM学习笔记(四)
- Inside COM学习笔记(五)
- COM Form "Inside COM" (1)
- 我的读博经历回顾与经验分享
- 畸形的从业观
- 可读写文件系统jffs2
- C++之自增、自减---面试
- Shell中字符串分割的三种方法
- Inside COM读书笔记-----类厂
- VMware与window共享的文件夹丢失
- hdu 1068 Girls and Boys 匈牙利
- [转]对.net系统架构改造的一点经验和教训
- 剑指offer面试题46求1+2+..+n不能用乘除法和选择循环,多种发散思维方法
- mysql sql 百万级数据库优化方案
- opencv学习心得(一)鼠标响应事件绘制轮廓
- Matlab Figure 图形保存以及 Simulink 中 Scope 窗口坐标标注(label)的设置
- socket阻塞与非阻塞,同步与异步、I/O模型