zoukankan      html  css  js  c++  java
  • C++_COM 入门

    COM即组件对象模型(Component Object Model)是一种跨应用和语言共享二进制代码的方法。COM明确指出二进制模块(DLLS和EXES)必须被编译成与指定的结构匹配,其定义的二进制标准独立于任何编程语言。这样就可以轻松地从任何编程语言中存取这些模块。

    coclass即组件对象类(component object class)被包含在DLL或EXE中,并包含着一个或多个接口的代码。组件对象类实现了这些接口。COM对象在内存中表现为组件对象类的一个实例。

    COM服务器是包含了一个或多个coclass的二进制文件(DLL或EXE)。

    GUID(谐音为“fluid”,意思是全球唯一标示符——globally unique identifier)是个128位的数字。它是一种独立于COM编程语言的标示方法。每一个接口和coclass有一个GUID。因为每一个GUID都是全球唯一的,所以避免了名字冲突(只要你用COM API创建它们)。有时你还会碰到另一个术语UUID(意思也是全球唯一标示符——universally unique identifier)。UUIDs和GUIDs在实际使用时的用途是一样的。
    类ID或者CLSID是命名coclass的GUID。接口ID或者IID是命名接口的GUID。

    HRESULT是COM用来返回错误和成功代码的整型数字。除此之外,别无它意,虽然以H作前缀,但没有句柄之意。

    创建COM对象

    为了创建COM对象并从这个对象获得接口,必须调用COM库的API函数,CoCreateInstance()。当你调用CoCreateInstance()时,它负责在注册表中查找COM服务器的位置,将服务器加载到内存,并创建你所请求的coclass实例。其原型如下:

    HRESULT CoCreateInstance (
        REFCLSID  rclsid,
        LPUNKNOWN pUnkOuter,
        DWORD     dwClsContext,
        REFIID    riid,
        LPVOID*   ppv );
    
     

    以下是参数解释:

    rclsid:coclass的CLSID,例如,可以传递CLSID_ShellLink创建一个COM对象来建立快捷方式。
    pUnkOuter:这个参数只用于COM对象的聚合,利用它向现有的coclass添加新方法。参数值为null表示不使用聚合。
    dwClsContext:表示所使用COM服务器的种类。本文使用的是最简单的COM服务器,一个进程内(in-process)DLL,
            所以传递的参数值为CLSCTX_INPROC_SERVER。注意这里不要随意使用CLSCTX_ALL(在ATL中,它是个缺省值),
            因为在没有安装DCOM的Windows95系统上会导致失败。
    riid:请求接口的IID。例如,可以传递IID_IShellLink获得IShellLink接口指针。
    ppv:接口指针的地址。COM库通过这个参数返回请求的接口。		
    

    删除COM对象

      你不用释放COM对象,只要告诉它们你已经用完对象。IUnknown是每一个COM对象必须实现的接口,它有一个方法,Release()。调用这个方法通知COM对象你不再需要对象。

    IUnknown接口

    每一个COM接口都派生于IUnknown。这个名字有点误导人,其中没有未知(Unknown)接口的意思。它的原意是如果有一个指向某COM对象的IUnknown指针,就不用知道潜在的对象是什么,因为每个COM对象都实现IUnknown。

    IUnknown 有三个方法:

    • AddRef() —— 通知COM对象增加它的引用计数。如果你进行了一次接口指针的拷贝,就必须调用一次这个方法,并且原始的值和拷贝的值两者都要用到。在本文的例子中没有用到AddRef()方法;
    • Release() —— 通知COM对象减少它的引用计数。参见前面的Release()示例代码段;
    • QueryInterface() —— 从COM对象请求一个接口指针。当coclass实现一个以上的接口时,就要用到这个方法来获得任何你需要的附加的接口指针;
    HRESULT IUnknown::QueryInterface (
        REFIID iid,
        void** ppv );
    
    以下是参数解释:
    iid:所请求的接口的IID。
    ppv:接口指针的地址,QueryInterface()通过这个参数在成功时返回这个接口。

    处理HRESULT

    HRESULT是个32位符号整数,其非负值表示成功,负值表示失败。HRESULT有三个域:程度位(表示成功或失败),功能码和状态码。

  • 相关阅读:
    智能移动机器人背后蕴含的技术——激光雷达
    Kalman Filters
    Fiddler抓HttpClient的包
    VSCode开发WebApi EFCore的坑
    WPF之小米Logo超圆角的实现
    windows react打包发布
    jenkins in docker踩坑汇总
    Using ML.NET in Jupyter notebooks 在jupyter notebook中使用ML.NET ——No design time or full build available
    【Linux知识点】CentOS7 更换阿里云源
    【Golang 报错】exec gcc executable file not found in %PATH%
  • 原文地址:https://www.cnblogs.com/bruce1992/p/14013519.html
Copyright © 2011-2022 走看看