library data;
uses
  SysUtils,windows,dialogs,
  Classes;var
 hMem:THandle;
const
 num=64;
function GetGlobalMem:THandle;export;
begin
 result:=hMem;
end;
{$R *.res}
exports
 getglobalMem;
begin
 hMem:=GlobalAlloc(gmem_Moveable and gmem_ddeshare,num);
 if hMem=0 then
 messagedlg('Could not allocate memory',mtWarning,[mbOK],0);
end.
动态链接库文件如上.
--------------------------------------------------------------------------------
在一个程序中有如下代码(Prog1)
procedure TForm1.Button1Click(Sender: TObject);
var
 hMem:THandle;
 pMem:Pchar;
begin
 hMem:=getGlobalMem;
 if hMem<>0 then
  begin
   pMem:=GlobalLock(hMem);
   if pMem<>nil then
      begin
      strPcopy(pMem,memo1.text);
      globalUnlock(hMem);
      end
   else
   Messagedlg('could not lock memory block',mtWarning,[mbOK],0);
  end;
end;
-------------------------------------------------------------------------
另一个程序中代码如下:(Prog2)
procedure TForm1.Button1Click(Sender: TObject);
var
 hMem:THandle;
 pMem:Pchar;
begin
 hMem:=getglobalMem;
 if hMem<>0 then
 begin
    pMem:=GlobalLock(hMem);
    if pMem<>nil then
      begin
        memo1.Text:=strpas(pMem);
        globalUnlock(hMem);
      end
     else
      messagedlg('couldnot lock memory block',mtWarning,[mbOK],0); 
 end;
end;
先运行程序Prog1,然后运行prog2,但是prog2的memo1中显示的结果与prog1中memo1输入的结果并不相同.
郁闷中,在delphi ide环境下单独运行prog1时,跟踪hmem和pmem的值,发现不管运行多少次,它们各自的值不变(pmem:$146638,hmem:1336888),(用view->debug window->cpu来查看1336888处的值,与我在memo1中输入的值相同,均为'test');
在delphi ide环境下单独运行prog2时,多次运行结果都是(pmem:$146638,hmem:1336888),但是用
view->debug window->cpu来查看1336888处的值,发现并不是'test'.这是为什么?
还有:当我后来把上面prog1和prog2中那两段代码分别放入同一个mdi下的两个子窗体中时,在每个子窗体中运行时,发现原prog2中的hmem和pmem的值发生了变化.
望高手指教!或者推荐一些能够解决我的疑惑的材料,不胜感激!

解决方案 »

  1.   

    尽最大的可能不要在Dll中使用GlobalAlloc,Alloc,New之类的内存分配函数,虽然Dll和Exe同处于一个地址空间中,但是Dll的堆地址和exe的堆地址不一样。
      

  2.   

    用view->debug window->cpu是否能看到全部物理地址空间的内容?
      

  3.   

    能看到这个Exe程序的虚拟地址内容,每个Win32应用程序都有自己独立的4GB虚拟地址空间!
      

  4.   

    谢谢!
    也就是说在ide下看到的地址都是虚拟地址,运行不同程序时,在ide下调试时看到的相等的地址,一般对应于不同的物理地址?
      

  5.   

    每个WIN32进程都有自己私有的4G虚拟内存空间,
    DLL可以实现模块重用,
    但是当DLL载入内存时,每被不同的进程载入一次,DLL中的全局变量都会有一份新的拷贝在它的宿主程序中,如果想实现所有DLL都能共享的数据,需要使用共享数据段DLL,目前只有VC的编译器可以实现。