想问一下关于VC++动态链接库中定义的变量问题。
我写了一个MFCDLL动态链接库,里面有个类,还有个全局变量HWNDhWnd;其中类里有个初始化函数StartHook(HWNDhwnd),我在这个函数里把参数hwnd赋...
我写了一个MFC DLL动态链接库,里面有个类,还有个全局变量HWND hWnd ;
其中类里有个初始化函数StartHook(HWND hwnd),我在这个函数里把参数hwnd赋值给dll中的全局变量hWnd,
hWnd = hwnd
DLL中还有个 函数
BOOL WINAPI EnumProc(HWND hwnd, LPARAM lParam)
{
if(hwnd)
{
LONG style = ::GetWindowLong(hwnd, GWL_STYLE) ;
if(style & ES_PASSWORD)
{
。。。。
::SendMessage(hWnd, WM_SETTEXT, 0, (LPARAM)szPass) ;
return TRUE ;
}
}
return TRUE ;
}
这个函数是给我上面说的hWnd窗口发送消息,我想问当EnumProc函数被调用的时候,hWnd还是
在StartHook中赋的值吗?如果不是应该怎么办呢?
我的确是在写钩子程序。我还有几个问题想问。
1、DLL到底是什么时候被加载什么时候被卸载的(对于隐式链接来说)?是第一次被调用的时候加载直到程序结束才卸载,还是调用完一个函数就卸载,然后下一次用到该DLL的时候再一次加载?
2、我的全局变量并不是你说要在几次不同的进程中共享,我的意思就是跟第一个问题有关的,我在一个DLL函数赋值了hwnd之后,这个函数用完之后DLL如果被卸载了,那么下一次调用DLL其他函数的时候,DLL需要重新加载,那么之前DLL函数设定的hwnd肯定就不存在了,如果真是用一次DLL加载一次的话,如何保存住设定的值呢?
3、对于共享数据区的问题。我在网上查到的语法都是
#pragma data_seg("share")
#pragma data_seg()
不像你说的前面还有push 后面还有pop。
然后全局数据区的名称前面还有个点 (..shvar)这是必须的吗?貌似不符合命名规则啊。 展开
其中类里有个初始化函数StartHook(HWND hwnd),我在这个函数里把参数hwnd赋值给dll中的全局变量hWnd,
hWnd = hwnd
DLL中还有个 函数
BOOL WINAPI EnumProc(HWND hwnd, LPARAM lParam)
{
if(hwnd)
{
LONG style = ::GetWindowLong(hwnd, GWL_STYLE) ;
if(style & ES_PASSWORD)
{
。。。。
::SendMessage(hWnd, WM_SETTEXT, 0, (LPARAM)szPass) ;
return TRUE ;
}
}
return TRUE ;
}
这个函数是给我上面说的hWnd窗口发送消息,我想问当EnumProc函数被调用的时候,hWnd还是
在StartHook中赋的值吗?如果不是应该怎么办呢?
我的确是在写钩子程序。我还有几个问题想问。
1、DLL到底是什么时候被加载什么时候被卸载的(对于隐式链接来说)?是第一次被调用的时候加载直到程序结束才卸载,还是调用完一个函数就卸载,然后下一次用到该DLL的时候再一次加载?
2、我的全局变量并不是你说要在几次不同的进程中共享,我的意思就是跟第一个问题有关的,我在一个DLL函数赋值了hwnd之后,这个函数用完之后DLL如果被卸载了,那么下一次调用DLL其他函数的时候,DLL需要重新加载,那么之前DLL函数设定的hwnd肯定就不存在了,如果真是用一次DLL加载一次的话,如何保存住设定的值呢?
3、对于共享数据区的问题。我在网上查到的语法都是
#pragma data_seg("share")
#pragma data_seg()
不像你说的前面还有push 后面还有pop。
然后全局数据区的名称前面还有个点 (..shvar)这是必须的吗?貌似不符合命名规则啊。 展开
4个回答
展开全部
我先声明一下……消息钩子这东西我有好长一段时间没有碰了,下面凭借印象说的东西不保证完全正确。
这和EXE是同一个道理,你有一个exe文件,运行多次,后一次在前一次结束之前就运行
这样就会同时有多个这个exe的进程在运行,此时它的全局变量会互相干扰吗?
我想你会说,不互相干扰。
DLL也是同样的道理。只是它更难理解的原因在于你用了SetWindowsHookEx这样的函数吧?(猜的,因为你的函数名是StartHook)。
用SetWindowsHookEx函数进行全局钩子之后,你的DLL文件会被加载到所有需要挂钩子的进程里,这样就相当于我之前说的exe文件被运行多次。这种情况下你的DLL在不同进程中会有独立的全局变量,所以在一个进程里赋值结果到了另一个进程里就看不到了。
在Windows核心编程这本书里面有详细介绍如何让一个全局变量在所有进程中互通的方法。简单地说,就是
HWND hWnd;
改为
#pragma data_seg(push)
#pragma data_seg(".shvar")
HWND hWnd = NULL; //一定要给初值,否则不会给你放在.shvar段内的样子。
#pragma data_seg(pop)
#pragma comment(linker, "/section:.shvar,RWS")
简单解释就是,这个全局变量将被放入DLL文件的.shvar段内,然后这整个段标记为在不同进程间共享。
这和EXE是同一个道理,你有一个exe文件,运行多次,后一次在前一次结束之前就运行
这样就会同时有多个这个exe的进程在运行,此时它的全局变量会互相干扰吗?
我想你会说,不互相干扰。
DLL也是同样的道理。只是它更难理解的原因在于你用了SetWindowsHookEx这样的函数吧?(猜的,因为你的函数名是StartHook)。
用SetWindowsHookEx函数进行全局钩子之后,你的DLL文件会被加载到所有需要挂钩子的进程里,这样就相当于我之前说的exe文件被运行多次。这种情况下你的DLL在不同进程中会有独立的全局变量,所以在一个进程里赋值结果到了另一个进程里就看不到了。
在Windows核心编程这本书里面有详细介绍如何让一个全局变量在所有进程中互通的方法。简单地说,就是
HWND hWnd;
改为
#pragma data_seg(push)
#pragma data_seg(".shvar")
HWND hWnd = NULL; //一定要给初值,否则不会给你放在.shvar段内的样子。
#pragma data_seg(pop)
#pragma comment(linker, "/section:.shvar,RWS")
简单解释就是,这个全局变量将被放入DLL文件的.shvar段内,然后这整个段标记为在不同进程间共享。
更多追问追答
追问
追问不能写很多字,我把追问写到问题补充里了,麻烦看看,谢谢。
追答
1、隐式链接的话,程序启动的时候加载(加载失败的话程序会拒绝启动),程序退出的时候卸载
2、因为隐式链接的时候不是用一次加载一次所以没这个问题。如果是用LoadLibary和GetProcAddress和FreeLibrary来操作,那么下一次加载的时候全局变量的值不会保留。
3、实现同一种功能有近乎无数种写法作为程序员应该是知道的(妈蛋看了一下vip认证楼主还是一本院校的……可恶我是二本院校)
命名规范我没仔细研究,只是看了它自带的那些section都有点我就也跟着加了点而已
我会提到要在不同进程之间共享的原因是假设了你已经发现hWnd不是自己赋的值……
如果你是用SetWindowsHookEx函数弄全局钩子,那么这种情况DLL确实是在多个进程中存在的。
展开全部
告诉你一个最简单的办法,你的枚举还有一个LPARAM lParam,你用这个参数把hWnd传到这个函数里去,这样你就不用定义全局变量。
追问
枚举函数是系统调用的吧,怎么通过lparam赋值啊?
追答
我猜你的EnumProc应该是EnumWindows调用的吧
BOOL EnumWindows(WNDENUMPROC lpEnumFunc, LPARAM lParam );
这个函数的lParam是会传到你的回调函数里去的,你可以把lParam定义为一个指针,你就想传什么就传什么了。
lParam
[in] Specifies an application-defined value to be passed to the callback function.
已赞过
已踩过<
评论
收起
你对这个回答的评价是?
展开全部
不使用全局变量 利用C++类的封装特性把 它改成私有的成员变量.......
已赞过
已踩过<
评论
收起
你对这个回答的评价是?
展开全部
全局变量的话,应该是的
如果不是应该我帮你搞定
同一个程序中加载调用DLL,应该是的
不同的程序都加载这个DLL的话,应该各是各的吧,呵呵
如果不是应该我帮你搞定
同一个程序中加载调用DLL,应该是的
不同的程序都加载这个DLL的话,应该各是各的吧,呵呵
追问
我是在同一个程序中加载的,但是我用Message输出hWnd的值,在StartHook(hwnd)中和EnumProc中的值是不一样的,StartHook中hWnd有值,而EnumProc中值是0。这说明hWnd没有保存到EnumProc就消失了。
追答
你的 全局变量HWND hWnd ; 是怎么定义的
在什么位置,主要是与大括号之间的位置,全局变量的话,要定义在所有大括号之外
确保是真正的全局变量,也可以试试全局静态成员变量
否则使用类静态成员也可以
或者类成员,但是在此调用时,类对象要是同一个对象
已赞过
已踩过<
评论
收起
你对这个回答的评价是?
推荐律师服务:
若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询