静态成员数据丢失. 实在不知道怎么回事了.都弄两天了.
直接看代码吧.
我做了个DLL的HOOK,DLL1是一个导出类.
下面是.H文件.有个static HWND hQQWnd;来存找到窗口的句柄,但这个变量到使用时变为了空.
class DLLAPI Dll1
{
public:
Dll1(void);
~Dll1(void);
//int add(int a, int b);
bool GetWnd(void);
private:
DWORD dwThreadID;
public:
static HHOOK hMouseHook;
static HWND hQQWnd;
static LRESULT CALLBACK MouseProc(int nCode,WPARAM wParam,LPARAM lParam);
};
下面是.CPP文件 在getwnd()里找窗口.付值给hQQWnd
#include "StdAfx.h "
#define DLLAPI __declspec(dllexport)
#include "Hook.h "
#include "Dll1.h "
HHOOK Dll1::hMouseHook=NULL;//在这里初始化
HWND Dll1::hQQWnd=NULL;
Dll1::Dll1(void)
{
}
Dll1::~Dll1(void)
{
}
extern CHookApp theApp;
bool Dll1::GetWnd(void)
{
HWND hParentWnd;
hQQWnd=FindWindow(NULL,_T( "外挂eBook "));
hParentWnd=GetForegroundWindow();
if(hQQWnd==NULL)
{
MessageBox(hParentWnd,_T( "没找到 "),_T( "没找到 "),MB_OK);
}
else
{
dwThreadID = GetWindowThreadProcessId(hQQWnd,NULL);
//SetWindowsHookEx(WH_CALLWNDPROC, CallWndProc, theApp.m_hInstance,dwThreadID);
hMouseHook=SetWindowsHookEx(WH_MOUSE, MouseProc, theApp.m_hInstance,dwThreadID);
MessageBox(hParentWnd,_T( "找到了 "),_T( "找到了 "),MB_OK);
}
return false;
}
下面是钩子函数 是一个DLL1的静态函数
LRESULT CALLBACK Dll1::MouseProc(int nCode,WPARAM wParam,LPARAM lParam)
{
CWnd* pWnd;
//出错就出在这,这时得到了一个桌面的dc 然后画的线从桌面的顶端开始画线.
//然后我测试了一下发现hQQWnd为NULL
//如果在这里加一句hQQWnd=FindWindow(NULL,_T( "外挂eBook ")); 重新付值 就正确了.
CClientDC dc(pWnd-> FromHandle(hQQWnd));
if(wParam==WM_MOUSEMOVE)
{
dc.MoveTo(0,0);
dc.LineTo(500,500);
}
return CallNextHookEx(hMouseHook,nCode,wParam,lParam);
}
在EXE里这是调用的代码.这是在EXE程序里调用的.
Dll1 dll1;
dll1.GetWnd();
都弄两天了不知道原因.C++真是太难了.
[解决办法]
static HWND hQQWnd;
别这么用了,别作为类的成员变量,把这个变量放到一个共享段中吧
/*把你的全局变量集中放到这个段中*/
#pragma data_seg( "MySec ")
HWND g_hQQWnd=NULL;
#pragma data_seg()
#pragma comment(linker, "/section:MySec,RWS ")
然后在DllName.def文件中,设置共享段:
LIBRARY HookObjectLib
EXPORTS
SEGMENTS
.MySec READ WRITE SHARED
这样你那个动态库在哪里使用,也不会丢掉数据。为什么会丢数据?这跟动态库的映射有关系,数据段也会跟着映射的。在A程序中时得到一个句柄,当DLL映射到B程序中时,会重新映射一个数据段,此时新数据段的那个句柄就是空的了。共享段不发生映射,只有一个拷贝,所有程序共享.