zoukankan      html  css  js  c++  java
  • Introduction to COM

    什么是COM?

    COM提供了一种在不同的应用程序和语言之间共享二进制代码的规范。

    COM定义了软件组件互相通讯的方式。它是一种二进制和网络标准,允许任意两个组件互相通讯,而不管它们是在什么计算机上运行(只要计算机是相连的),也不管计算机运行的是什么操作系统(只要该操作系统支持COM),也不管该组件是用什么语言编写的。

    COM还提供了位置透明性:当使用COM组件时,该组件是进程内Dll、本地exe还是位于其他机器上的组件,都无所谓。

     

    为什么需要COM?

    使用COM编写的二进制模块必须匹配一些特定的数据结构。COM规范同样也定义COM对象在内存中应该如何被组织。这份二进制代码同样也不能依赖任何语言层面的特征。

    COM对象的结构使用与C++虚函数相同的结构。所以很多COM使用C++编写,但是严格来说COM与编写该COM的语言是不想关的,因为最后的二进制代码可以被任何语言使用。

    COM并不是Win32相关的,理论上,COM可以被移植到任何操作系统上,但是现实中COM依然只是Windows世界的东西。

    COM基本术语

    1.interface:一个接口可以看做是一组称为方法的函数。接口名以"I"打头,如"IShellLink",在C++中,接口即是一个只含有纯虚函数的抽象基类。

    2.coclass:component object class的简称。coclass用来实现接口。一个COM对象是coclass在内存中的一个实例(instance)。注意COM"class"跟C++"class"不是一个东西,虽然COM class 的实现通常都是C++ class。

    3.COM Server:含有一个或多个coclass的二进制模块(DLL或者EXE)。

    4.Registration:向Windows注册,登记COM Server的位置和入口。Unregistration是一个相反的过程:从Windows中移除掉这个登记。

    5.GUID:globally unique identifier。一个128位的数。COM使用语言无关的GUID作为标识。每一个interface和coclass都有一个GUID,因为GUID是全世界范围内唯一的。所以避免了名字冲突。有时候GUID也被称为UUID(universally unique identifier)。一个coclass的class ID称为CLSID;一个interface的interfaceID称为IID。

    6.HRESULT:一个整数类型的值,COM使用它来返回成功或者错误码。可以使用Windows错误码查询来获取HRESULT所代表的字符含义。

    基接口(base interface):IUnknown

    每一个COM接口都要从IUnknown接口继承。

    IUnknown这个名字的含义是:如果你拥有一个指向IUnknown接口的COM对象指针,那个你无从知道它真正指向的对象是什么,因为COM中的每一个对象都实现了这个接口。

    这个接口有三个方法:

    AddRef、

    Release、

    QueryInterface。其中QueryInterface用于在获取某个COM的一个接口指针后,查询该COM的其他接口指针。

    HRESULT IUnknown::QueryInterface ( REFIID iid, void** ppv );

     

    使用COM

    1.创建一个COM对象:C++中使用new操作符或者直接在栈上创建;创建COM对象则要调用COM library中的一个API(CoCreateInstance)。

    2.删除COM对象:C++中,使用delete操作符或者在栈上的对象超出作用域以后会自动析构。但是在COM中,所有的对象拥有它们自己的引用计数(reference count)。调用者必须在使用完COM对象以后通知它(减少引用计数)。COM对象在引用计数到达0时,自动从内存中释放自己。

    当调用CoCreateInstance函数时,它查询注册表中的CLSID,读取COM server的位置,将其加载到内存中并创建函数所请求的coclass的一个实例。需要注意的是,在使用函数CoCreateInstance之前,确保你的程序已经初始化了COM library,并且需要在程序退出时卸载它,分别调用CoInitialize和CoUninitialize函数。

    COM中的字符串操作

    只要注意到COM中的字符串都是Unicode的,就应该没有问题的。习惯于使用Unicode并在与COM的交互中使用Unicode,就不会有任何问题。

    当使用ANSI时,需要自己处理Unicode与ANSI之间的转换。

    除了常规的转换方法外,ATL提供了几个宏处理这种转换:W2A()、OLE2A()、OLE2CA()等。

    其他细节:与COM有关的宏

    STDMETHOD():包含了virtual关键字和HRESULT返回类型以及__stdcall调用约定。STDMETHOD_()与之相同,但是允许指定非HRESULT的返回值。

    PURE:与C++中的"=0"效果相同,将一个函数声明为纯虚函数。

    STDMETHODIMP:对应于STDMETHOD()的实现,相应地,STDMETHODIMP_()与STDMETHOD_()对应。

    STDAPI:包含了返回类型和调用约定,由于STDAPI的扩展方式,使用了此宏以后不能再使用__declspec(dllexport)。可以使用".DEF"文件完成类似功能。

    参考资料:

    http://blog.csdn.net/winglet/article/details/2872342

  • 相关阅读:
    api.js
    vue开关
    vue 单选框自定义
    vue 笔记
    Flutter 检测网络连接 监听网络变化
    lutter 调用原生硬件 Api 实现扫码
    flutter 支付宝支付流程以及用 Flutter 在 Android Ios 中实现支付宝支付
    js+css 动效+1的效果
    Vue -- filters 过滤器、倒计时效果
    移动端如何实现两行点点点?
  • 原文地址:https://www.cnblogs.com/CathyGao/p/2291826.html
Copyright © 2011-2022 走看看