(VC++)DLL设置钩子函数,如何让回调函数能修改DLL中的全局变量

在做一个模块测试,将MFC程序中的主窗口句柄、成员变量、全局变量作为参数传入DLL并将值保存到DLL的全局变量中,发现在钩子函数HOOK的回调函数中调用到的DLL全局变量都是空值(吓尿了),也就是说从外部传入的值虽然保存在DLL的全局变量里,但是钩子函数的回调函数根本获取不到!!!可是需要这些变量跟MFC程序进行消息交互呀!!怎么会这样?为什么会这样?

其实每次触发钩子回调函数的都是不同的线程,每个线程系统都分配了不同的地址空间,仅仅是名字相同【恍然大悟呀】。

被多个线程共用,要想使用该全局变量,那么该全局变量必须是共享的!!所以要把这些全局变量放到一个叫做DLL共享数据段的东东内。

但是注意,共享数据段的设置需要符合一定的前提条件,否则白搭。

以下是核心代码:

#include "stdafx.h"
#include <Dbt.h>
#include "DeviceChangeDetect.h"

#define WM_MY_TEST (WM_USER+100)


/*
数据段内变量需要主要以下几点,否则数据段设置不生效:
a、共享段的大小空间必须确定,不要使用string、CString等这种大小不明确的【用数组代替】
b、定义了一个变量,必须初始化,不管是什么类型都要初始化
c、要写完整,一共【①设置权限】【②指定数据段的名字及权限】【③数据段结束】
*/

//①设置数据段为可读可写可共享
#pragma comment(linker,"/section:.ShareSeg,rws")

//②设置共享数据段,目的是让模块中[包括回调函数]都能操作全局变量,每个变量都必须初始化
#pragma data_seg(".ShareSeg")
HHOOK glhHook=NULL; //钩子句柄。
HINSTANCE glhInstance=NULL; //DLL实例句柄。
HWND gHwnd = NULL;
WCHAR wcWndName[256]={0};

//③共享数据段结束
#pragma data_seg()

extern "C" LRESULT WINAPI DeviceChangeProc(int nCode,WPARAM wParam,LPARAM lParam)

int nW = 1;
int nL = 2;
switch(nCode) 


case HC_ACTION: 
PCWPSTRUCT pMsg = PCWPSTRUCT(lParam); 
if ( pMsg->message == WM_DEVICECHANGE ) 

switch( pMsg->wParam ) 

case DBT_DEVICEARRIVAL:
//gHwnd = FindWindow(NULL,_T("DLLCatchDevChange"));//使用该方法可以找到指定的窗口句柄
::SendMessage(gHwnd,WM_MY_TEST,nW,nL);//与传入的句柄窗口进行消息交互
break; 
case DBT_DEVICEQUERYREMOVE: 
// Handle device removal request 
AfxMessageBox(_T("COM Change"));
break; 
case DBT_DEVICEREMOVECOMPLETE: 
// Handle device removal 
AfxMessageBox(_T("COM Has removed"));
break; 



return CallNextHookEx(glhHook,nCode,wParam,lParam);
}


extern "C" int APIENTRY DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID lpReserved)
{
switch (dwReason)  
{  
case DLL_PROCESS_ATTACH:  
glhInstance = (HINSTANCE)hInstance;//非常重要,此时要先获得这个模块的句柄  
break;  
case DLL_THREAD_ATTACH:  
break;  
case DLL_THREAD_DETACH:  
break;  
case DLL_PROCESS_DETACH:  
break;  
default:  
break;  
}  
//AfxMessageBox(L"Entry");
return TRUE;
}

//安装全局钩子。
HHOOK CDeviceChangeHook::Start(HWND hWnd)
{
gHwnd = hWnd;
if (NULL == gHwnd)
{
AfxMessageBox(_T("hWnd is NULL"));
return NULL;
}
glhHook = SetWindowsHookEx(WH_CALLWNDPROC/*WH_GETMESSAGE*/,DeviceChangeProc,glhInstance,0);//根据模块句柄glhInstance设置钩子函数
return glhHook;
}

//卸载全局钩子。
BOOL CDeviceChangeHook::Stop()
{
BOOL bResult = TRUE;
if( glhHook )
bResult = UnhookWindowsHookEx(glhHook);//卸载钩子。
return bResult;
}

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值