有这样一个现象:
当exe和dll引用同一个forms.pas文件以后,那么请看下面代码:library mydll
interface
uses 
windows,sysutils,forms;procedure  test;external;stdcall;
implementation
{$R *.res}
procedure  test;external;stdcall;
begin
  showmessage(application.title);
end;
end.///////////////////////////////////program myexeuses
windows,sysutils,forms;
{$R *.res}
var
hlib:dword;
p:tprocedure;
begin
  application.initialize;
  application.title:='ok!'
  hlib:=loadlibrary("mydll.dll");
  p:=getprocaddress(hlib,"test");
  if assigned(p) then p();//竟然能够显示'ok!'
  freelibrary(hlib);
  application.run;
end.//////////////////////////我们知道,application是forms.pas单元中的全局变量。
dll里面并没有对application做初始化,但是调用test的时候,dll里访问了在exe中做好了初始化的application变量。问题:是不是因为同一个进程中exe和dll共享一切内存,完全透明,并且只要引用了同一个单元,那么在任何编译好的pe文件中,该单元的资源,比如全局变量、常量、函数等,都被固化到了相同的rva地址?

解决方案 »

  1.   

    d5开发指南中讲过
    dll中的application对象与调用它的程序是分离的,
    应该是没有什么关系
    但是为什么显示ok,不知道了~
    等高人吧~
      

  2.   

    不是这样的,dll的那个application的title就是exe的application.title如果你这样调用
      application.initialize;
      application.title := 'abc';
      hlib:=loadlibrary("mydll.dll"); //now the library cache the application module 
                                      //name to it's title property, the value is
                                      //abc
      application.title :='ok!'       //now we change to 'ok', but the dll application
                                      //property Title will not changed  p:=getprocaddress(hlib,"test");
      if assigned(p) then 
      begin
         p();                         //here, it will be show 'abc' rather 'ok'
      end;
      freelibrary(hlib);
      application.run;
      

  3.   

    动态库里加入uses ShareMem有用吗
      

  4.   

    "//now the library cache the application "?怎么个cache法?如何解答:“是不是因为同一个进程中exe和dll共享一切内存,完全透明,并且只要引用了同一个单元,那么在任何编译好的pe文件中,该单元的资源,比如全局变量、常量、函数等,都被固化到了相同的rva地址?”
      

  5.   

    因为你的DLL间接引用了Controls,而Controls会导致Application的初始化
    你可以参考TApplication.Create()的代码,它里面有对Title属性的初始化
    对于一个DLL或Package,它的Title被初始化为宿主应用程序(exe)的Module Name,
    也就是title,但是一旦这个DLL的Application对象的Title被初始化后,不管exe方面怎样变化它就不再变化了,所以我说它把module name cache起来了,关于这一点,
    详见TApplication.GetTitle()的代码以上就是你给出的例子以及我改后的例子之所以得出那样的结果的原因
    至于你说的是不是因为同一个进程中exe和dll共享一切内存,完全透明,
    并且只要引用了同一个单元,那么在任何编译好的pe文件中,该单元的资源,
    比如全局变量、常量、函数等,都被固化到了相同的rva地址?”则是错误的,dll中的所有单元和exe中的所有单元都是分离的,各自都有一个副本
      

  6.   

    再补充一下dll中的所有单元和exe中的所有单元都是分离的,各自都有一个副本
    的,除非它们都build with runtime library,那么这些被build with
    的runtime library中的单元的数据则是共享的
      

  7.   

    我看了这些代码,但是能解释一下,哪里可以看出来title 被 module name cache啊。
    -------------------
    function TApplication.GetTitle: string;
    var
      Buffer: array[0..255] of Char;
    begin
      if FHandleCreated then
        SetString(Result, Buffer, GetWindowText(FHandle, Buffer,
          SizeOf(Buffer))) else
        Result := FTitle;
    end;procedure TApplication.SetTitle(const Value: string);
    begin
      if FHandleCreated then
      begin
        if (GetTitle <> Value) or (FTitle <> '') then
        begin
          SetWindowText(FHandle, PChar(Value));
          FTitle := '';
        end;
      end
      else
        FTitle := Value;
    end;这里只是设定ftitle,设置ftitle而已啊,当然同时设定了windowtest。
      

  8.   

    你这 jie115(守望红木) ,真会借花献佛阿!