例:
有两个应用分别为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也应该有办法的
有两个应用分别为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也应该有办法的
解决方案 »
- 关于Msn标签的问题
- delphi+oracle开发人事档案管理系统的问题
- Delphi+SQL
- delphi+sqlserver,恢复备份数据出现的问题
- 如何实现当chart控件的mousedown时激发chart控件里某个series的click事件或者chart控件的clickseries事件?
- 100分,请教SQL SERVER2000存储过程的调试方法
- delphi dbgrid拖动滚动条时如何像Memo一样适时显示数据??
- 请问一个提取数据的解决方法。
- 急:怎样使DBGrid能一次修改多条记录?
- 请教(DELPHI),1.怎样做一个从treeview到本地硬盘上某个指定目录的对应
- 现在的公司都变换名称 招人的吗? (夏商舟 =?尊网商通)
- cxGrid主从表实现问题
只要在各个工程的搜索路径指向同一个dll单元。
我上面说的可能还有些不完整, 通过getListobj返回的list对像,应该只能读不能写
要写入的话,应使用dll中的函数,比如 function additem(student:PStudent);
dll中的大概写法
---
function additem(student:PStudent);
var
pStudent:PStudent;
begin
getmem(pStudent,sizeof(TStudent));
copyMemory(pStudent, student, sizeof(sizeof(TStudent)));
g_List.add(pStudent);
end;
这样写是让内存是dll分配的,加载他的dll都能共享到它的内存
-----
---------
一个学生结构体
PStudent = ^TStudent;
TStudent = record
ID:integer;//学号
age:integer;//年龄
name:array[0..32] of char;//姓名
end
-----------
我在app1.exe中
procedure fun();
var
st:TStudent;
begin
st.id := 1;
st.name ='aaa';
st.age = 20;
additem(@st); //这里使用上面的dll中的additem函数来添加数据。
end;效果是在app2.exe中使用getlistobj也能读取到上面的的st.id=1,st.name='aaa'这个数据
{ }
{ 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;
destructor TPublicVars.Destroy;
begin
UnmapViewOfFile(FShareMem);
CloseHandle(FMapFile);
inherited;
end;function TPublicVars.GetHandle: THandle;
begin
Result := FShareMem.Handle;
end;procedure TPublicVars.SetHandle(AValue: THandle);
begin
FShareMem.Handle := AValue;
end;function TPublicVars.GetReportID: Integer;
begin
Result := FShareMem.ReportID;
end;procedure TPublicVars.SetReportID(AValue: Integer);
begin
FShareMem.ReportID := AValue;
end;function TPublicVars.GetReportType: Integer;
begin
Result := FShareMem.ReportType;
end;procedure TPublicVars.SetReportType(AValue: Integer);
begin
FShareMem.ReportType := AValue;
end;function TPublicVars.GetStatFile: string;
begin
Result := FShareMem.StatFile;
end;procedure TPublicVars.SetStatFile(AValue: string);
var
iMaxCount: Integer;
begin
ZeroMemory(@FShareMem.StatFile[0], Length(FShareMem.StatFile));
iMaxCount := Min(Length(FShareMem.StatFile), Length(AValue));
StrMove(@FShareMem.StatFile[0], PChar(AValue), iMaxCount);
end;function TPublicVars.GetTestConfig: string;
begin
Result := FShareMem.TestConfig;
end;procedure TPublicVars.SetTestConfig(AValue: string);
var
iMaxCount: Integer;
begin
ZeroMemory(@FShareMem.TestConfig[0], Length(FShareMem.TestConfig));
iMaxCount := Min(Length(FShareMem.TestConfig), Length(AValue));
StrMove(@FShareMem.TestConfig[0], PChar(AValue), iMaxCount);
end;procedure TPublicVars.SetMapFile(AValue: string);
var
iMaxCount: Integer;
begin
ZeroMemory(@FShareMem.MapFile[0], Length(FShareMem.MapFile));
iMaxCount := Min(Length(FShareMem.MapFile), Length(AValue));
StrMove(@FShareMem.MapFile[0], PChar(AValue), iMaxCount);
end;function TPublicVars.GetMapFile: string;
begin
Result := FShareMem.MapFile;
end;function TPublicVars.GetSiteData: string;
begin
Result := FShareMem.SiteData;
end;procedure TPublicVars.SetSiteData(AValue: string);
var
iMaxCount: Integer;
begin
ZeroMemory(@FShareMem.SiteData[0], Length(FShareMem.SiteData));
iMaxCount := Min(Length(FShareMem.SiteData), Length(AValue));
StrMove(@FShareMem.SiteData[0], PChar(AValue), iMaxCount);
end;function TPublicVars.GetDestFile: string;
begin
Result := FShareMem.DestFile;
end;procedure TPublicVars.SetDestFile(AValue: string);
var
iMaxCount: Integer;
begin
ZeroMemory(@FShareMem.DestFile[0], Length(FShareMem.DestFile));
iMaxCount := Min(Length(FShareMem.DestFile), Length(AValue));
StrMove(@FShareMem.DestFile[0], PChar(AValue), iMaxCount);
end;function TPublicVars.GetHintMsg: string;
begin
Result := FShareMem.HintMsg;
end;procedure TPublicVars.SetHintMsg(AValue: string);
var
iMaxCount: Integer;
begin
ZeroMemory(@FShareMem.HintMsg[0], Length(FShareMem.HintMsg));
iMaxCount := Min(Length(FShareMem.HintMsg), Length(AValue));
StrMove(@FShareMem.HintMsg[0], PChar(AValue), iMaxCount);
end; function TPublicVars.GetReportState: TReportState;
begin
Result := FShareMem.ReportState;
end;procedure TPublicVars.SetReportState(AValue: TReportState);
begin
FShareMem.ReportState := AValue;
end;end.
具体楼主可以下载一个 <delphi 5 开发人员指南> 第九章 里面有详细介绍,还有实例,看过后保证会
#pragma data_seg("Shared")
是VC的使用方法,Delphi不能这么用。解决方案是建立内存映射文件
或者可以使用汇编,形成obj文件,再由Delphi连接编译。
可以参照:
http://www.delphibbs.com/delphibbs/dispq.asp?lid=3088031
我在说明一下实现的效果。
这是一个多层的框架分为:数据库(各种数据库或配置文件)、中间层业务(dll或能共享数据的东西)、界面层(可执行程序用于显示、输入、输出)1. 界面层应用程序A运行:加载了中间层dll2. 中间层dll读取数据库或配置文件, 生成对应的内存数据结构,用链表或树容器来管理,具有查找添加、删除、修改等操作.
dll会导出这些操作函数。3. 界面层A调用dll的函数显示出对应的数据。 4. 界面层B程序,也加载dll,发现这些容器对像已经创建就不在读数据库或配置(相似一个单件模式),显示出的数据与A程序一样。5. 程序A,修改了一个数据。 程序B先前会设置一个回调函数到dll中,dll响应一个OnDataChange事件,B程序会生新刷新界面,到dll中读取新的数据。
unsigned 你说的DCOM我不太了解,能详细点吗?能推介些资料或书籍吗?
比如说我现在有一种数据结构:
一个链表,装了一个结构体有两个字段:一个是SerIP,另个还是连表,这个连表里装了一个结构体里面有clientIP,计算机名
IP List
|192.168.1|list|------->|192.168.1.100|计算机1|
|192.168.2|list| |192.168.1.101|计算机2|
|192.168.3|list|
我开始想,是不是要所有的类都要有一个SaveToData的方法,把这个类中的数据定义成一段连续的内存段,然后通过指针返回到客户端,客户端用LoadFromData的方法来还原。但是这样做觉得很复杂了,所有的对象都要这样定义。
http://download.csdn.net/source/824285
Windows
;
type
TManagedObject = class(TObject)
{Management Properties}
private
FManagementCount : Integer; //对象引用计数
public
{structor}
constructor Create;
public
{Management}
procedure Free;
function Attach:TManagedObject;
function Detach: Integer;
end;
implementation{TManagedBaseObject}
{structor}
constructor TManagedObject.Create;
begin
Inherited Create;
FManagementCount := 1;
end; {Management}
function TManagedObject.Attach : TManagedObject;
begin
Result := Nil;
if InterlockedIncrement(FManagementCount) = 1 then
begin
InterlockedDecrement(FManagementCount);
Exit;
end;
Result := self;
end; function TManagedObject.Detach : Integer;
begin
Result := InterlockedDecrement(FManagementCount);
end; procedure TManagedObject.Free;
begin
if Detach>0 then
Exit;
Inherited;
end;end.
我的QQ号是:6346289