读书人

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

发布时间: 2012-03-27 13:44:24 作者: rapoo

如何多个应用程序共享同一个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的对象添加一个方法,然后在客户端调用该方法即可。

读书人网 >.NET

热点推荐