注册 登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

隐龙 为了一生的信念

今日默默沉于水,他日飞腾在九天...

 
 
 

日志

 
 

【转载】[原创]Exe、Dll中全局变量共享的最佳办法!  

2013-09-07 20:33:53|  分类: Delphi |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |

在dll中全局变量的共享是个老问题,网上也早有许多的议论,但总是讲解得意犹未尽。这里我也不一一比较各种方法的优劣。我就我认为最容易实现且没任何问题的办法作个说明。

基本思路是这样的:把全局变量所有参数声明在一个指针结构中,通过创建内存映射文件来使exe和各dll之间实现数据共享。

1、声明全局变量:

  
type
PGlobalVar=^TGlobalVar; TGlobalVar=packed record sCpbm:string; //产品编码 sCpmc:string; //产品名称 sVersion:string; //产品版本 User:TUser; sPathApp,sPathImage,sPathGlobal,sPathData,sPathTemp:string; //各路径变量 sLocalDBConnectionString:string;//本地数地库连接 sCodeFileName:string; //codes.xml global_MessageList: TMessageList; //全局消息列表 by lzs end;
var
  GlobalVar:PGlobalVar;    //全局变量
2、创建内存映射文件:
procedure OpenGlobalVariantData(const aAppHandle:HWND);
const
  const_GlobalVariantFileName = 'GlobalMemoryVariantOf%d';
var
  sLpName:string;
begin
  //每个程序用的内存文件名应该不一样,防止不同程序之间变量串用,以appHandle来区分
  //创建一个内存文件映射对象。
  if GlobalVarMapHandle=0 then //如果<>0则已经创建,无需再建
  begin
    sLpName:=Format(const_GlobalVariantFileName,[aAppHandle]);
    GlobalVarMapHandle := OpenFileMapping(FILE_MAP_ALL_ACCESS,false,
      pchar(sLpName)); //先尝试打开
    if GlobalVarMapHandle=0 then     //打开不成功再创建
    begin
      GlobalVarMapHandle := CreateFileMapping($FFFFFFFF, nil, page_readWrite, 0,
        sizeof(TGlobalVar), pchar(sLpName));
      if GlobalVarMapHandle = 0 then
        RaiseLastOSError;  
    end;
    //把文件的视图映射到调用进程的地址空间,该函数的返回值就是该对象的首地址。
    if GlobalVarMapHandle<>0 then  //创建成功
    begin
      GlobalVar := MapViewOfFile(GlobalVarMapHandle, File_map_all_Access,
         0, 0, 0{size--0是打开整个内存文件});
      if not Assigned(GlobalVar) then  //映射失败
      begin
        CloseHandle(GlobalVarMapHandle);
        RaiseLastOSError;    
      end;
    end;
  end;
end;

procedure CloseGlobalVariantData;
begin
  if assigned(GlobalVar) then
    unmapViewOfFile(GlobalVar);
  if GlobalVarMapHandle<>0 then
    closeHandle(GlobalVarMapHandle);
end;

finalization
  CloseGlobalVariantData;//这里统一关闭全局变量即可
 
3、在正确的位置来创建内存映射文件:
EXE程序中创建的位置是工程文件中:
  Application.Initialize;
  OpenGlobalVariantData(Application.Handle);
DLL程序中创建的位置是dll调用方法中application传递进来之后:
  Application:=MainApp;
  screen:=MainScr;
  OpenGlobalVariantData(Application.Handle);//如果需要全局变量,这个要写上,必须写在application后面
 
这样初始化之后,在exe和dll中,只要uses全局变量的声明单元文件,即可对全局变量GlobalVar里的所有参数进行各种操作,与正常无任何区别。
补充一句:网上许多声音说全局变量中最好不要用string变量,而是用pchar或string[20]之类的东东来代替,但这样操作起来相当的麻烦。经过我的试验,直接用string类型并无出现问题,前提是所有的exe、dll工程中,第一个必须uses ShareMem。
  评论这张
 
阅读(198)| 评论(1)
推荐 转载

历史上的今天

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2018