科技行者

行者学院 转型私董会 科技行者专题报道 网红大战科技行者

知识库

知识库 安全导航

至顶网软件频道基础软件COM编程技术基础之二

COM编程技术基础之二

  • 扫一扫
    分享文章到微信

  • 扫一扫
    关注官方公众号
    至顶头条

详细介绍COM接口在COM组件中的作用以及实现COM接口的方法

作者:中国电波传播研究所青岛分所郎锐 来源:yesky 2007年10月20日

关键字:

  • 评论
  • 分享微博
  • 分享邮件
类厂所支持的用以创建组件的接口是IClassFactory,该接口从IUnknown派生,并具有两个自己的接口成员函数CreateInstance()和LockServer()。这两个成员函数分别用于创建COM组件对象和控制组件的生存期。下面先给出CreateInstance()的函数声明:

HRESULT __stdcall CreateInstance(IUnknown* pIUnknownOuter, const IID& iid, void** ppv);

  可以看出,这个用于创建组件对象的CreateInstance()函数并未包含一个用来接受CLSID的参数,显然该函数将只能创建同某个CLSID相应的组件。对于一个类厂,由于只能通过CreateInstance()函数去创建组件,因此只能创建与某个特定CLSID相应的组件。

  创建类厂的CoGetClassObject()函数将接收一个CLSID作为参数并返回指向类厂对象IClassFactory接口的指针。客户将可以通过此指针来创建所需要的组件并返回某接口的指针。通过此指针,客户将可以直接调用新创建的COM对象接口的成员函数,从而获得COM对象的所有服务。

  在用CoGetClassObject()创建类厂对象时,如果COM对象是进程内组件(组件与客户处于同一进程地址空间,通常多以DLL形式存在),CoGetClassObject()将调用DLL模块的DllGetClassObject()引出函数并把clsid、iid和ppv等参数传递进去以创建类厂,并返回类厂对象的接口指针。

  如果COM对象是进程外组件(拥有独立的进程地址空间,通常多以EXE形式存在),则CoGetClassObject()将要首先启动组件进程,并一直等待到组件进程通过CoRegisterClassObject()函数将类厂注册到COM后,才会返回COM中相应的类厂信息。一旦组件进程退出,此注册的类厂对象也就不再有效,需调用CoRevokeClassObject()函数予以通知。图4展示了通过类厂创建组件的过程:


图4 组件的创建过程

  客户程序对COM组件的调用主要分对进程内组件调用和进程外调用两种情况。在具体过程上却并没有什么太大的区别。为了能够使用COM库提供的API函数,首先要用CoInitialize()初始化COM库。

  虽然通过CLSID和ProgID都可以标识一个组件,但ProgID显然要比CLSID更易于理解和使用,因此通常很少直接使用CLSID,而是通过使用CLSIDFromProgID(),根据ProgID得到组件的CLSID。进而以此返回的CLSID作为参数去调用CoGetClassObject()以创建类厂对象并返回类厂接口指针。通过该指针调用类厂对象的CreateInstance()接口成员函数,执行结果将创建与CLSID相应的组件对象并返回IUnknown接口指针。通过此接口的QueryInterface()成员函数将能够进一步获过程将是隐含进行的,使用更为简单。
取组件的其他接口指针,从而使用组件提供的各种服务。

  最后,通过Release()函数释放接口指针。如果使用的进程内组件,在调用CoUninitialize()函数释放COM库资源之前,应首先调用CoFreeUnusedLibraries()将其从内存卸载。由于在CoCreateInstance()函数内部实现了对CoGetClassObject()的调用并一直完成了类厂对象接口函数对组件的创建和类厂对象的释放,因此对于客户,类厂

查看本文来源

的全部使用
    • 评论
    • 分享微博
    • 分享邮件
    邮件订阅

    如果您非常迫切的想了解IT领域最新产品与技术信息,那么订阅至顶网技术邮件将是您的最佳途径之一。

    重磅专题
    往期文章
    最新文章