DLL何时需共享内存管理器

     Delphi创建DLL时,IDE自动生成的文档中写得很清楚,当在DLL中以动态数组或String做为参数或返回值时(即RTL自动维护的数据类型),请在每个工程文件的第一个单元加上ShareMem。这样就可以使宿主程序与DLL共享内存管理器了!

这样的话,在发布程序时需要把borlndmm.DLL一同发布!

问题1:

 

为何要加到工程文件的第一个单元?

      对于DLL和主程序这样的程序结构来说,使用2个内存管理器,在返回的数据类型为string的话,仅仅在主程序中将内存管理器中将引用数加1,而DLL的引用数不变,这样当退出DLL过程中,由于引用数为0,要对返回值进行释放,由于主程序中的数据为一个地址,将DLL地址释放,主程序中必然发生AV错误!

     至于为什么ShareMem必须放第一个单元,那是因为Delphi的单元文件的initialization
的执行顺序,与dpr中引用这个单元的顺序有关;dpr中某单元引用越靠前,则某单元的initialization就越先执行!而我们程序的 内存管理器的"替换"过程就是在initialization块里实现的 看看Delphi的ShareMem里的一点代码就了解了!

 

问题2:

为何要把borlndmm.dll一同发布?

请参见ShareMem.pas源码!

  1. procedure InitMemoryManager;  
  2. var  
  3.   SharedMemoryManager: TMemoryManager;  
  4.   MM: Integer;  
  5. begin  
  6.   // force a static reference to borlndmm.dll, so we don't have to LoadLibrary   
  7.   SharedMemoryManager.GetMem := SysGetMem;  
  8.   
  9.   MM := GetModuleHandle(DelphiMM);  
  10. {$IFDEF GLOBALALLOC}  
  11.   SharedMemoryManager.GetMem := xSysGetMem;  
  12.   SharedMemoryManager.FreeMem := xSysFreeMem;  
  13.   SharedMemoryManager.ReallocMem := xSysReallocMem;  
  14. {$ELSE}  
  15.   SharedMemoryManager.GetMem := GetProcAddress(MM,'@Borlndmm@SysGetMem$qqri');//动态调用borlndmm中的GetMem函数来使主调与dll内存管理器共享   
  16.   SharedMemoryManager.FreeMem := GetProcAddress(MM,'@Borlndmm@SysFreeMem$qqrpv');  
  17.   SharedMemoryManager.ReallocMem := GetProcAddress(MM, '@Borlndmm@SysReallocMem$qqrpvi');  
  18. {$ENDIF}  
  19.   SetMemoryManager(SharedMemoryManager);  
  20. end;  
  21.   
  22. initialization  
  23.   if not IsMemoryManagerSet then  
  24.     InitMemoryManager;//!!!!  

 

 

最后建议大家使用FastMM,borlndmm.dll已经成为一般过去式了~

 

http://blog.csdn.net/liangpei2008/article/details/4112886  笑青天

posted @ 2014-06-03 17:54  梁彦坤  阅读(648)  评论(0编辑  收藏  举报