怎样在dll中声明系统全局的变量?给你100分

rummy 2003-10-16 04:04:08
怎样在dll中声明系统全局的变量?给你100分
...全文
124 15 打赏 收藏 转发到动态 举报
写回复
用AI写文章
15 条回复
切换为时间正序
请发表友善的回复…
发表回复
pankun 2003-10-16
  • 打赏
  • 举报
回复
我写的一个DLL,里面就实现了全局变量.
uses
SysUtils,windows, Messages;

const
WM_UNSUBCLASS = WM_USER + 1001; {卸载子类化消息}
WM_NEWMESSAGE = WM_USER + 1002; {通知监视窗口拦到了新消息}
HOOK_EVENT_NAME = 'MyHook';

type
PMyDLLVar = ^TMyDLLVar;
TMyDLLVar = record
SubClass: Boolean; {是否已经子类化}
HookWindow, SpyWindow: LongWORD; {要安装HOOK的窗口及用于接收消息的窗口}
hHook: LongWORD; {HOOK句柄}
OldWndProc: pointer; {旧的窗口过程}
MsgHwnd: LongWORD;
Msg: TMessage;
end;

var
DLLData: PMyDLLVar; //这儿DLLData指向内存文件映射处,所以是个全局变量.

{---------------------------------------}
{函数名:NewWndProc
{函数功能:新的窗口过程
{函数参数:hHwnd:窗口句柄 Msg:消息ID
{ wParam, lParam:消息参数
{函数返回值:下一个窗口过程的返回值
{---------------------------------------}
function NewWndProc(hHwnd, Msg, wParam, lParam: LongWORD): Longint; stdcall;
begin
if Msg = WM_UNSUBCLASS then {如果收到卸载子类化消息就恢复以前的WndProc}
begin
SetWindowLong(DLLData^.HookWindow, GWL_WNDPROC, longint(DLLData^.OldWndProc));
exit;
end;
{这儿是把收到的消息放在映射的内存中,我们自己的程序可以通过读这个内存来得到监视到的消息.}
DLLData^.Msg.Msg := Msg;
DLLData^.Msg.WParam := wParam;
DLLData^.Msg.LParam := lParam;
DLLData^.MsgHwnd := hHwnd;
{给监视窗口发送拦载新消息的消息}
SendMessage(DLLData^.SpyWindow, WM_NEWMESSAGE, 0, 0);
{这儿可以添加自己对目标进程消息处理的代码,因为己经是在目标进程的地址空间内,现在可以为所
欲为 ^_^)
Result := CallWindowProc(DLLData^.OldWndProc, hHwnd, Msg, wParam, lParam);
end;

{------------------------------------}
{过程名:HookProc
{过程功能:HOOK过程
{过程参数:nCode, wParam, lParam消息的相
{ 关参数
{------------------------------------}
procedure HookProc(nCode, wParam, lParam: LongWORD);stdcall;
var
hEvent: THandle;
begin
if not DllData^.SubClass then {如果此窗口未子类化}
begin {保存窗口过程地址并子类化}
if hEvent <> 0 then
begin
WaitForSingleObject(hEvent, INFINITE);
CloseHandle(hEvent);
end;
DLLData^.OldWndProc := pointer(GetWindowLong(DLLData^.HookWindow, GWL_WNDPROC));
SetWindowLong(DLLData^.HookWindow, GWL_WNDPROC, integer(@NewWndProc));
DLLData^.SubClass := True;
hEvent := OpenEvent(Synchronize, False, HOOK_EVENT_NAME);
end;
{调用下一个Hook}
CallNextHookEx(DLLData^.hHook, nCode, wParam, lParam);
end;


{------------------------------------}
{函数名:InstallHook
{函数功能:在指定窗口上安装HOOK
{函数参数:HWindow:要安装HOOK的窗口
{ SWindow:用于接收消息的窗口
{返回值:成功返回TRUE,失败返回FALSE
{------------------------------------}
function InstallHook(HWindow, SWindow: LongWORD):Boolean;stdcall;
var
ThreadID: LongWORD;
hEvent: THandle;
begin
Result := False;
DLLData^.hHook := 0;
DLLData^.HookWindow := HWindow;
DLLData^.SpyWindow := SWindow;
{得到指定窗口的线程ID}
ThreadID := GetWindowThreadProcessId(HWindow, nil);
{给指定窗口挂上钩子}
hEvent := CreateEvent(nil, True, False, HOOK_EVENT_NAME);
DLLData^.hHook := SetWindowsHookEx(WH_GETMESSAGE, @HookProc, Hinstance, ThreadID);
SetEvent(hEvent);
CloseHandle(hEvent);
if DLLData^.hHook > 0 then Result := True; {是否成功HOOK}
end;

{------------------------------------}
{过程名:UnHook
{过程功能:卸载HOOK
{过程参数:无
{------------------------------------}
procedure UnHook;stdcall;
begin
{发送卸载子类化消息给指定窗口}
SendMessage(DLLData^.HookWindow, WM_UNSUBCLASS, 0, 0);
DLLData^.SubClass := False;
{卸载Hook}
UnhookWindowsHookEx(DLLData^.hHook);
end;

{------------------------------------}
{过程名:DLL入口函数
{过程功能:进行DLL初始化,释放等
{过程参数:DLL状态
{------------------------------------}
procedure MyDLLHandler(Reason: Integer);
var
FHandle: LongWORD;
begin
case Reason of
DLL_PROCESS_ATTACH:
begin {建立文件映射,以实现DLL中的全局变量}
FHandle := CreateFileMapping($FFFFFFFF, nil, PAGE_READWRITE, 0, $ff, 'MYDLLDATA');
if FHandle = 0 then
if GetLastError = ERROR_ALREADY_EXISTS then
begin
FHandle := OpenFileMapping(FILE_MAP_ALL_ACCESS, False, 'MYDLLDATA');
if FHandle = 0 then Exit;
end else Exit;
DLLData := MapViewOfFile(FHandle, FILE_MAP_ALL_ACCESS, 0, 0, 0);
if DLLData = nil then
CloseHandle(FHandle);
end;
DLL_PROCESS_DETACH:
if Assigned(DLLData) then
begin
UnmapViewOfFile(DLLData);
DLLData := nil;
end;
DLL_THREAD_ATTACH:;
DLL_THREAD_DETACH:;
end;
end;

{$R *.res}
exports
InstallHook, UnHook, HookProc;

begin
DLLProc := @MyDLLHandler;
MyDLLhandler(DLL_PROCESS_ATTACH);
end.

herofy 2003-10-16
  • 打赏
  • 举报
回复
可以的我看到过,没作过
yaven365 2003-10-16
  • 打赏
  • 举报
回复
delphi动态库中应该是没有全局变量,我刚刚试验国

vc动态库中绝对没问题
pankun 2003-10-16
  • 打赏
  • 举报
回复
TO:yaven365(天涯网客)

比如说我要用HOOK监视其它进程的消息.监视到了消息要发到我的窗口中.这儿不用DLL全局变量你说怎么实现嘛.怎么保存窗口句柄?因为监视进程消息的代码已被注入到其它进程中了.
pankun 2003-10-16
  • 打赏
  • 举报
回复
转HK兄的一篇贴子.他这贴子是讲的进程之间的内存共享,改一下就可以实现DLL中的全局变量了

http://www.csdn.net/develop/read_article.asp?id=20538
yaven365 2003-10-16
  • 打赏
  • 举报
回复
99%的问题都可以不用全局变量,你可以数出你为什么用全局变量

然后大家帮你找出不用全局变量的方法

这里的全局变量指的是动态库中的全局变量
liufuyahong 2003-10-16
  • 打赏
  • 举报
回复
其他人有更好的办法么?
pankun 2003-10-16
  • 打赏
  • 举报
回复
用内存文件映射可以做到..
dickeybird888 2003-10-16
  • 打赏
  • 举报
回复
恐怕是不行,因为dll必须要一个东西来调用,那在调用之前你dll的变量根本就不可能产生啊!又何谈全局变量呢?
reallike 2003-10-16
  • 打赏
  • 举报
回复
嘻嘻,好玩。
fengyvn 2003-10-16
  • 打赏
  • 举报
回复
参数传递是最安全的办法.
slley 2003-10-16
  • 打赏
  • 举报
回复
不建议在dll中使用全局变量。
snowfog 2003-10-16
  • 打赏
  • 举报
回复
关注
free007 2003-10-16
  • 打赏
  • 举报
回复
为了数据的安全,不要在dll中使用全局变量
liufuyahong 2003-10-16
  • 打赏
  • 举报
回复
据我所知,Dll中的变量不能直接调用,只能通过参数来传递。

procedure GetGlobalVal(var s)
begin
s:=globalvalue;
end;

function GetGlobalval:returntype
begin
Result:=globalvalue;
end;

其他人有更好的办法么?

5,379

社区成员

发帖
与我相关
我的任务
社区描述
Delphi 开发及应用
社区管理员
  • VCL组件开发及应用社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧