C++ COM学习笔记(一)浅谈COM初始化

来源:互联网 发布:大熊猫自然保护区知乎 编辑:程序博客网 时间:2024/05/30 04:05
com提倡的就是灵活,只有减少公开性才能减低耦合,在创建COM实例是也是如此,所有的COM实例都是通过CoCreateInstance()函数创建,那么怎么才能通过这一个API创建出自己现有的实例对象呢?

我们可以先看看函数原型

STDAPI CoCreateInstance(  REFCLSID rclsid,     //Class identifier (CLSID) of the object  LPUNKNOWN pUnkOuter, //Pointer to controlling IUnknown  DWORD dwClsContext,  //Context for running executable code  REFIID riid,         //Reference to the identifier of the interface  LPVOID * ppv         //Address of output variable that receives                        // the interface pointer requested in riid);


其中参数说明:

第一个参数:待创建组件的CLSID。

第二个参数:用于聚合组件。

第三个参数:dwClsContext的作用是限定所创建的组件的执行上下文。

第四个参数:iid为组件上待使用的接口的iid。

第五个参数:输出实例化指针

其实要搞清楚怎么创建自己想要的实例,我们只关心第一个参数rclsid和第四个参数riid,下面我主要说说这两个参数:1、rclsid:首先要搞清楚我们的要穿件的组建对象是更具一个组建来创建的,通俗点就是在一个DLL(虽然有时会时一个EXE)文件,那么系统分有这么多DLL还有自己创建的组建DLL我们怎么才能区分他们呢?总不要把他们都记着吧,就算记得加载起来也比较麻烦,所以我们就为么一个组建(DLL)进行唯一标示,用一个CLSID表示,这里第一个参数rclsid就是我所说的CLSID标示符,他能保证全球唯一性,有了这个标示符还不行,例如我知道这个标示符怎么才能在自己的进程exe中加载对应的DLL呢?为了解决这个问题,我们又想到的系统注册表,不懂注册表的同学就把他理解成键值对(key-value),在我们创建组建DLL时通常会把CLISD标示符和DLL路径以这种键值对的方式保存在注册表HKEY_CLASSES_ROOT的若干子项中(应为也只有创建组建者才能轻松的完成),有了这个注册表我们的CoCreateInstance()函数就可以查找到路径进行动态加载组建了。(不过DLL是不会自己执行任何动作来进行注册这个键值对,通常我们的组建DLL创建者会留一个接口DllRegisterServer()来给辅助程序来加载创建2、riid:加载好多组建并不能立即创建我们所需要的实例,想一想一个组建如果能创建不同的两个实例我们该如何区分创建呢?,所以这里就要用到riid,他是一个接口标示符,有了这个就能唯一确定创建实例了。其实这个参数最后传给了COM的一个核心接口虚函数HRESULT QueryInterface(REFIIDiid,void **ppvObject)来进行查询创建实例,其实说这个是创建实例还不如说是查询,应为在QueryInterface()之前我们已经通过CoCreateInstance()函数new出来了一个实例,QueryInterface()说只是进行一个类型的转换更合适,为什么要转换,这里有涉及到虚类继承时,基类和父类转换时之间会有只能的一些偏移的原因。


总结一下:CoCreateInstance ()通过rclsid查找注册表找到组建的二进制文件DLL位置,然后通过riid进行实例化穿件,最后通过第五个参数输出实例化对

0 0
原创粉丝点击