zoukankan      html  css  js  c++  java
  • COM笔记-动态链接

    在实现了IUnknown之后,组件和客户之间只是一种非常松散的连接,这使用组件和客户各自可以发生变化而不会对对方造成什么影响。

    下面讨论如何将组件放入到动态链接库(dll)中。

    关于DLL更多内容可以参考我的其它文章:

    DLL-基本概念

    DLL-创建DLL

    DLL-使用DLL

    http://www.cnblogs.com/fangyukuan/archive/2010/06/20/1761430.html
    http://www.cnblogs.com/fangyukuan/archive/2010/06/20/1761464.html
    http://www.cnblogs.com/fangyukuan/archive/2010/06/21/1761666.html

    组件的创建

    在客户可以获取某个组件接口指针之前,它必须先将相应 的DLL装载到其进程空间中并创建此组件。这里创建组件的方法是临时性的,后面我还有其它方法(它客户和组件进一步分隔开来)。

    之前说到QueryInterface函数的时候给出了CreateInstance可以建立一个组件的实例并给客户返回一个IUnknown接口指针(见:QueryInterface函数)这个函数是DLL中唯一需要显式链接的函数。客户其它所需要的所有函数都可以通过接口指针而访问到。

     

     

    DLL中输出CreateInstance函数

    extern "C"进行标记要输出的函数。

    例如:

    extern "C"  IUnknown *CreateInstance()

    {

    IUnknow *pI = (IUnknown *)(void *)new CA;

    pI->AddRef();

    Return pI;

    }

    在函数的定义前加上可防止C++ 编译器在函数名称上加上类型信息。例如在不加extern "C"时,Microsoft Visual C++ 将把CreateInstance变成:

    CreateInstance@@YAPAUUnknown@@XZ

    其它的编译器可能会使用另外某种名称修改方法。

     

    还需要建立一个的DEF文件。

    LIBRARY Search.dll

    EXPORTS

    导出函数名

     

    DLL的装载

    CreateInstance

    装载DLL并调用其中所输出的函数

    为装载指定的DLL,CallCreateInstance调用了Win32的LoadLibray函数:

    GetProcAddress使用LoadLibray返回的句柄和待调用的函数名称,返回一个指向此函数的指针

    FARPROC GetProcAddress(

      HMODULE hModule,

      LPCWSTR lpProcName

    );

     

     

    复制代码
    typedef IUnknown* (*CREATEFUNCPTR)();

    IUnknown* CallCreateInstance(char* name)
    {
    // Load dynamic link library into process.
    HINSTANCE hComponent = ::LoadLibraryA(name) ;
    if (hComponent == NULL)
    {
    cout << "CallCreateInstance: Error: Cannot load component." << endl;
    return NULL;
    }

    // Get address for CreateInstance function.
    CREATEFUNCPTR CreateInstance
    = (CREATEFUNCPTR)::GetProcAddress(hComponent, "CreateInstance");
    if (CreateInstance == NULL)
    {
    cout << "CallCreateInstance: Error: "
    << "Cannot find CreateInstance function."
    << endl;
    return NULL;
    }

    return CreateInstance();
    }
    复制代码

     

    使用DLL的原因

    DLL可以共享它们所链和的应用程序的地址空间。

    客户和组件是通过接口进行交互的。一个接口实际上是一个指向函数的指针列表(vtbl)。组件为vtbl分配内存并用每个函数的地址来初始化此表格。

    为了使用vtbl客户应该能 够访问组件 其vtbl民分配的内存,它还必须能够理解组件放入到vtbl中的各个地址。

     

    进程外服务器具有与客户不同的地址空间,但我们将仍然使用Dll来帮助实现进程外服务器同客户之间的交流。如下图显示了DLL如何映射到其客户的地址空间。

     

    此外的关键之外在于,当得到组件的一个接口指针时,连接客户和组件的唯一中介是接口的二进制结构。当客户查询组件的某个接口时,它所请求的实际上是具有特定格式的一块内存。当组件返回一个接口指针时,它告诉的实际上是些块内存的地址。

    由于接口是在客户和组件都能够访问的内存中,因此这种情况实际上与当然和组件在同一个EXE文件中是相同的。

    (vs2008)代码下载:http://www.box.net/shared/zhktgzojlj

     

    本文地址:http://www.cnblogs.com/fangyukuan/archive/2010/06/09/1755150.html 

     

  • 相关阅读:
    基于深度学习的人脸识别系统,识别率高达99.7%
    计算机设计思想 —— 虚拟化
    计算机设计思想 —— 类比、建模与隐喻(同构)
    机器学习:simple linear iterative clustering (SLIC) 算法
    如何快速批量修改ArcGIS中的图层设置
    ubuntu 安装cuda 成功
    深度学习攒机配置
    修改hosts文件(判断是否为管理员/以管理员权限运行脚本)
    添加环境变量(永久生效)
    获取管理员组用户
  • 原文地址:https://www.cnblogs.com/bruce1992/p/14873345.html
Copyright © 2011-2022 走看看