飘云阁

 找回密码
 加入我们

QQ登录

只需一步,快速开始

查看: 3941|回复: 4

关于应用程序和插件或DLL之间的关系

[复制链接]
  • TA的每日心情
    奋斗
    2017-4-20 22:12
  • 签到天数: 1 天

    [LV.1]初来乍到

    发表于 2008-6-27 11:42:31 | 显示全部楼层 |阅读模式
    (作者:不得闲
         原创贴,请尊重版权,转载请注名)
    原文:http://blog.csdn.net/suiyunonghen/archive/2008/03/22/2207649.aspx

         近来一段日子,希望做一个可扩展功能的系统,于是就需要插件等接口的支持。前次说了准备用BPL来做插件,原因是因为DLL中的类和其宿主程序中的Delphi类是不同的,从而有时候或许或出问题。而且我用BPL也用来做了几个东西,也都正常,上次的例子提出来的也倒正常。可是当我将他用来做我的系统的插件的时候就出现问题了。
    难道是用法有错!经过反复的转换,写了好几种方法,也请教了几个高手,但是最终还是一样的有问题。想来想去
    忽然想到了在Delphi做DLL的时候,一般需要引进DLL的参数都有Application,Screen等!那个时候,只是看到别人说在DLL中的Application,Screen和在应用程序中的Application,Screen对象是不同的,如果要使他们之间没有错误的进行相互进行消息的访问和传递,就需要将主应用程序的Application传递过去,但是至于为什么不同,倒是从来没有想过!直到近来遇到这个问题,才想到这个上面来。
       先来看看Application和Screen这两个对象是如何在什么地方产生的。在Forms单元中Application是个全局变量,而在Delphi中,程序的所有消息处理都是先交给该对象来处理的,然后才转到下面来由各个控件等进行处理的。而该Application又是在什么时候产生的呢?通过追踪得知该对象产生于Controls单元中的InitControls方法,而该方法在Controls单元在初始化的时候就被调用,也就是说只要引用Controls就会产生Application对象。我们都知道在EXE程序中是有Application对象的,那么编译DLL的时候,同样如果引用了Controls单元则产生了一个Application对象,而该DLL中的Application对象显然和EXE中的对象不是同一个对象,那么当你在DLL中想要操作其宿主程序的Application的话,你就必须将你EXE程序中的对象传递过来替换Dll中的对象。这样你操作的才是和Exe中一样的对象。这就是为什么需要传递Application对象到Dll中去的原因了。
      而我遇到的这个问题也同样是这样,在BPL包中会用一个控件,而该控件引用的一个单元会初始化一些东西,这个初始化就会生成一些全局变量,而控件在使用的时候要通过这些全局对象来操作!然而我的控件只在EXE程序中而不在BPL包中,所以我在通过一个包中包含一些单元达到初始化一些方法和过程不能成功!原因就是我的EXE中控件需要的那个全局对象初始化在EXE中,而在调用BPL包初始化的时候,又会产生一个新的存在于包中的全局对象,所以无论我怎样初始化,初始化的也是包中的全局对象,EXE中的全局对象根本不会变。此时,将该全局对象传递过去,替换包中的全局对象,则初始化成功。
    PYG19周年生日快乐!
  • TA的每日心情
    擦汗
    2020-7-7 10:06
  • 签到天数: 2 天

    [LV.1]初来乍到

    发表于 2008-7-1 09:05:19 | 显示全部楼层
    虽然EXE和DLL之间在运行时使用了相同的进程空间,但DLL与EXE的变量在相互之间是独立的,也就是说DLL的所有变量对EXE而言是局部变量,非全局的,同样EXE的所有变量对DLL也是局部变量。

    要相互访问这些相对局部的变量,就需要定义一些输出函数来引用这些变量。


    例如:在test.exe中定义函数:
    function GetApplication:TApplication;export;
    begin
      result:=Application;
    end;

    在DLL中可以导入该函数来以访问EXE中的Application变量.
    =========================================================================
    从这里可以看出,EXE也可以当做DLL使用的,因为EXE和DLL使用了相同的PE文件格式.
    PYG19周年生日快乐!
  • TA的每日心情
    奋斗
    2017-4-20 22:12
  • 签到天数: 1 天

    [LV.1]初来乍到

     楼主| 发表于 2008-7-9 12:30:11 | 显示全部楼层
    未必如楼上所说!他们所在的空间不是线性的!
    而且有些全局变量,就算你将其导入出来,一样访问会出问题的!很多Delphi的控件就不能封装到DLL中去使用,特别是那些有全局变量的控件包,而包中的很多方法是通过和应用程序之间传递消息来进行的。比如Dream控件包中的设计器,PaxScript脚本引擎!
    PYG19周年生日快乐!
  • TA的每日心情
    擦汗
    2020-7-7 10:06
  • 签到天数: 2 天

    [LV.1]初来乍到

    发表于 2008-7-11 09:26:04 | 显示全部楼层
    原帖由 suiyunonghen 于 2008-7-9 12:30 发表
    未必如楼上所说!他们所在的空间不是线性的!
    而且有些全局变量,就算你将其导入出来,一样访问会出问题的!很多Delphi的控件就不能封装到DLL中去使用,特别是那些有全局变量的控件包,而包中的很多方法是通过和应用 ...


    Windows系统为每个进程都分配了0到4GB的空间,虽然这个空间在物理内存中是由几个不连续内存块组成的,但通过对应用程序透明的地址转换机制转换后,就可以用连续的线性地址访问这些不连续的物理内存块,因此相对应用程序来说,系统给每个进程分配的空间就是连续的,线性的!!!!

    访问每个程序变量,不管它是全局的还是局部的,都必须遵循它的访问规则,破坏这些访问规则,当然会引起意想不到的问题!!!
    PYG19周年生日快乐!
  • TA的每日心情
    开心
    前天 20:20
  • 签到天数: 1246 天

    [LV.10]以坛为家III

    发表于 2008-7-11 21:11:27 | 显示全部楼层
    /:012 哇都这么精辟呀。
    我刚开始看黑客基地的教程/:013
    PYG19周年生日快乐!
    您需要登录后才可以回帖 登录 | 加入我们

    本版积分规则

    快速回复 返回顶部 返回列表