学习利用COM组件

来源:互联网 发布:淘宝拍单免费送衣服 编辑:程序博客网 时间:2024/05/06 14:25

From My Blog(http://bloglong123king.sourceforge.net/?p=193)

一、简介

COM(Component Object Model, 组件对象模型)是一种用来创建可以交互的软件组件的平台无关的、分布式的、面向对象的系统。

COM is a platform-independent, distributed, object-oriented system for creating binary software components that can interact.

COM is the foundation technology for Microsoft's OLE (compound documents) and ActiveX® (Internet-enabled components) technologies, as well as others.

OLE以及ActiveX都是以COM为基础的;COM组件需要由面向对象的语言开发。

二、COM的构成

COM的核心内容是Object对象,Object会向使用COM的客户程序Client暴露一组或者多组的相关函数,每一组相关的函数称为一个接口Interface

每个接口都必须继承自IUnknown接口。IUnknown接口提供三个函数:

  • QueryInterface

  1. HRESULT QueryInterface(
  2.     REFIID iid,
  3.     void ** ppvObject
  4. );
  • AddRef

  1. ULONG AddRef(void);
  • Release

  1. ULONG Release(void);

一个Object通常会暴露多个Interface,如果Client当前已经得到了其中的一个接口InterfaceA,但是Client想要访问该Object的另外一个接口InterfaceB,这里Client应该调用QueryInterface方法:

  1. InterfaceA* interface_a = ...;
  2. InterfaceB* interface_b;
  3.  
  4. HRESULT hResult = interface_a.QueryInterface(IID_INTERFACEB, &interface_b);
  5. if (hResult == S_OK){
  6.     ...
  7. }


三、怎样查看本机提供哪些COM服务

通过RegDllView(http://www.nirsoft.net/utils/registered_dll_view.html)工具,可以查看到当前系统中注册的COM组件的image path以及类的GUID等信息。

我们随便选取其中的一个COM服务的image用CFF Explorer(http://www.ntcore.com/exsuite.php)查看信息,发现它的导出函数只有4个:

dll_image_exp

其中,DllGetClassObject的原型如下:

  1. HRESULT DllGetClassObject(
  2.    REFCLSID rclsid,
  3.    REFIID riid,
  4.    LPVOID* ppv 
  5. ) throw( );

这个函数与QueryInterface比较类似,都是获取一个COM组件提供的某个接口对象。
区别在于:

  • QueryInterface是在已经知道了该COM组件暴露的一个接口的前提下,再获取到该组件的其他接口;
  • 而DllGetClassObject是在知道该组件的CLSID以及需要访问接口的IID的情况下,要获取COM的相应接口。

你可以这样认为,我们第一次获取某个组件的接口,使用DllGetClassObject,而以后就可以调用刚刚获取到的接口的QueryInterface成员来继续获取该组件的其他接口了。

四、以VirtualBox SDK为例学习在C++程序中调用COM组件

利用VirtualBox SDK需要做以下准备工作:

    • 安装VirtualBox(https://www.virtualbox.org/)
    • 下载VirtualBox SDK(http://download.virtualbox.org/virtualbox/),到对应版本的目录下去找sdk包下载;解压到某个本地目录(假设为SDK_DIR)
    • 打开Windows命令行,cd到SDK_DIR\installer目录(在Windows7下可以先通过资源管理器进入SDK_DIR\installer目录,再通过Shift+F10, w快速打开命令行), 执行vboxapisetup.py build,以及vboxapisetup.py install安装sdk到系统中
    • 通过Visual Studio新建一个C++ Console项目,注意不要勾选
    • SDK_DIR\bindings\mscom\lib\VirtualBox_i.c以及SDK_DIR\bindings\mscom\include\VirtualBox.h拷贝并添加到新建的C++项目中去
    • VirtualBox SDK的文档在SDK_DIR\sdk\docs\html\index.html页面

接下来我们可以添加如下代码:

  1. #include "VirtualBox.h"
  2.  
  3. int _tmain(int argc, _TCHAR* argv[])
  4. {
  5.     CoInitialize(NULL); 
  6.  
  7.     IVirtualBox* pVirutalBox = NULL; 
  8.     HRESULT hr = CoCreateInstance(CLSID_VirtualBox,
         NULL,
         CLSCTX_ALL,
         IID_IVirtualBox,
         (void**)&pVirutalBox); 
  9.     if (SUCCEEDED(hr) && (pVirutalBox != NULL)) 
  10.     {
  11.         BSTR pszSettingsPath = NULL;
  12.         HRESULT hResult = pVirutalBox->get_SettingsFilePath(&pszSettingsPath);
  13.         if (hResult != S_OK)
  14.         {
  15.             printf("We got some error, 0x%08X\n", hResult);
  16.         }
  17.         wprintf(L"VirtualBox Settings Path : %s\n", pszSettingsPath);
  18.     } 
  19.  
  20.     CoUninitialize(); 
  21.  
  22.     return 0;
  23. }
原创粉丝点击