首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > .NET > .NET >

怎么多个应用程序共享同一个dll中的对象

2012-03-27 
如何多个应用程序共享同一个dll中的对象!例:有两个应用分别为app1, app2, 他们都加载了同一个dll: shareli

如何多个应用程序共享同一个dll中的对象!
例:
  有两个应用分别为app1, app2, 他们都加载了同一个dll: sharelib.dll 。 
  在Sharelib.dll 中导出一个函数 为 function GetListObj:TList; 返回一个list对象,也就是List的指针。函数内容大概为
  ----------
  var
  g_List:TList;
  
  function GetListObj:TList; stdcall;
  begin
  //没有就创建
  if not Assigned(g_List) then
  g_List := TList.Create;
 
  resutl := g_List;
  end;
  -----------
  这时app1 程序用这个dll函数GetListObj返回的List对象,使用List的add方法 ,app2程序中使用此函数得到的对应可以读取到app1中添加的内容。
 
  如何能实现这个效果,请高手指教一下。 我看到有VC中可以使用
-------------
  #pragma data_seg("Shared")
  std::list <User_Info> SrvSockList;
  std::list <User_Info>::iterator pSockList;
  SOCKET m_Listensock=0;
  HWND g_hWnd = NULL; 
  #pragma data_seg()
  #pragma comment(linker, "/Section:Shared,rws") 
------------
我想delphi也应该有办法的

[解决办法]
用内存映射,下面是我写的一段代码给你参考。

Delphi(Pascal) code
{****************************************************************************}{                                                                            }{       SharedMem.pas{       Comment:真正的实现了服务和应用程序共享内存{                                                                            }{****************************************************************************}unit MsgSharedMem;interfaceuses  Windows, Messages, SysUtils, Math;const  CSharedMemSize = 1024*1024*3;  CSharedMemName = 'Global\FleetReportSharedMemorty';  WM_CreateReport = WM_USER + 1001;           WM_EndReport = WM_USER + 1002;              CSocketEndTag = #13#10;type  //报表执行状态  TReportState = (rsFinished, rsInexistent, rsWaiting, rsRunning, rsException, rsCanceled);  TShareMem = record    Handle: THandle;                               ReportID: Integer;                             ReportState: TReportState;                     ReportType: Integer;                              StatFile: array[0..1024*1024] of Char;         TestConfig: array[0..1024*1024] of Char;       MapFile: array[0..1024*100] of Char;           SiteData: array[0..1024*100] of Char;          DestFile: array[0..1024*2] of Char;            HintMsg: array[0..1024*3] of Char;           end;  PShareMem = ^TShareMem;  TPublicVars = class  private    FShareMem: PShareMem;    FMapFile: THandle;    procedure SetHandle(AValue: THandle);    function GetHandle: THandle;    procedure SetReportID(AValue: Integer);    function GetReportID: Integer;    procedure SetReportState(AValue: TReportState);    function GetReportState: TReportState;    procedure SetReportType(AValue: Integer);    function GetReportType: Integer;    procedure SetStatFile(AValue: string);    function GetStatFile: string;    procedure SetTestConfig(AValue: string);    function GetTestConfig: string;    procedure SetMapFile(AValue: string);    function GetMapFile: string;    procedure SetSiteData(AValue: string);    function GetSiteData: string;    procedure SetDestFile(AValue: string);    function GetDestFile: string;    procedure SetHintMsg(AValue: string);    function GetHintMsg: string;  public    constructor Create(ANew: Boolean);    destructor Destroy; override;    property Memory: PShareMem read FShareMem;    property Handle: THandle read GetHandle write SetHandle;    property ReportID: Integer read GetReportID write SetReportID;    property ReportState: TReportState read GetReportState write SetReportState;    property ReportType: Integer read GetReportType write SetReportType;    property StatFile: string read GetStatFile write SetStatFile;    property TestConfig: string read GetTestConfig write SetTestConfig;    property MapFile: string read GetMapFile write SetMapFile;    property SiteData: string read GetSiteData write SetSiteData;    property DestFile: string read GetDestFile write SetDestFile;    property HintMsg: string read GetHintMsg write SetHintMsg;  end;implementation{ TPublicVars }resourcestring  CouldNotMapViewOfFile = 'Could not map view of file.';const  SECURITY_NULL_SID_AUTHORITY = 0;  SECURITY_WORLD_SID_AUTHORITY = 1;  SECURITY_LOCAL_SID_AUTHORITY = 2;  SECURITY_CREATOR_SID_AUTHORITY = 3;  SECURITY_NT_AUTHORITY = 5;  SECURITY_NULL_RID = 0;  SECURITY_WORLD_RID = 0;  SECURITY_LOCAL_RID = 0;  SECURITY_CREATOR_OWNER_RID = 0;  SECURITY_CREATOR_GROUP_RID = 1;  ACL_REVISION = 2; type  ACL_SIZE_INFORMATION = record    AceCount: DWORD;    AclBytesInUse: DWORD;    AclBytesFree: DWORD;  end;  ACE_HEADER = record    AceType: BYTE;    AceFlags: BYTE;    AceSize: WORD;  end;  PACE_HEADER = ^ACE_HEADER;  ACCESS_ALLOWED_ACE = record    Header: ACE_HEADER;    Mask: ACCESS_MASK;    SidStart: DWORD;  end;          constructor TPublicVars.Create(ANew: Boolean);var  SecMem: SECURITY_ATTRIBUTES;  aSD: SECURITY_DESCRIPTOR;begin  inherited Create;  { 创建一个任何用户都可以访问的内核对象访问权 }  InitializeSecurityDescriptor(@aSD, SECURITY_DESCRIPTOR_REVISION);  SetSecurityDescriptorDacl(@aSD, True, nil, False);  SecMem.nLength := SizeOf(SECURITY_ATTRIBUTES);  SecMem.lpSecurityDescriptor := @aSD;  SecMem.bInheritHandle := False;  FMapFile := CreateFileMapping($FFFFFFFF, @SecMem, PAGE_READWRITE, 0, CSharedMemSize, CSharedMemName);  FMapFile := OpenFileMapping(File_Map_All_Access, False, CSharedMemName);  if (FMapFile = 0) then  begin    raise Exception.Create(SysErrorMessage(GetLastError));    OutputDebugString(PChar(SysErrorMessage(GetLastError)));  end  else  begin                                   // 成功    FShareMem := MapViewOfFile(FMapFile, File_Map_All_Access, 0, 0, CSharedMemSize);    OutputDebugString(PChar(SysErrorMessage(GetLastError) + ',Handle=' + IntToStr(Handle)));  end;end; 


[解决办法]
用内存映射文件共享Dll中的数据
具体楼主可以下载一个 <delphi 5 开发人员指南> 第九章 里面有详细介绍,还有实例,看过后保证会
[解决办法]
顶 内存映射文件。。
#pragma data_seg("Shared") 
是VC的使用方法,Delphi不能这么用。

解决方案是建立内存映射文件
或者可以使用汇编,形成obj文件,再由Delphi连接编译。
可以参照:
http://www.delphibbs.com/delphibbs/dispq.asp?lid=3088031
[解决办法]
为DCOM的对象添加一个方法,然后在客户端调用该方法即可。

热点排行