关于PostMessage()的两个隐患

ecai 2001-03-07 10:02:00
1) PostMessage()在DEBUG版本和Release版本的区别
对于一个自定义message的handler,其标准声明形式为:
afx_msg LRESULT OnMyMessage(WPARAM wParam,LPARAM lParam);
由于我写程序时懒惰,而且通常不需要使用参数,所以经常定义成:
afx_msg void OnMyMessage();
即忽略了返回值和参数。返回值定义成void没有影响,但是如果不显式定义参数则会造成问题:在DBBUG版本中运行正常,在RELEASE版本中使用PostMessage()发送同一条自定义消息时,第二次会产生一般保护性错误!只要加上参数的显式定义就没有问题了。
请教:为什么会出现这种情况?我找遍了MSDN,似乎没有提醒注意这个问题。我写了一个很简单的程序发送两次自定义消息,证明的确会有这个问题。
2) PostMessage()不发送时耗尽资源
使用::PostMessage() (API版本的PostMessage)时,如果HWND参数为NULL时,如
UINT wParam,lParam;
。。。。。 // 给参数赋值
::PostMessage(glpMyWnd->GetSafeHwnd(),UM_MY_MESSAGE,(WPARAM)wParam,(LPARAM)lParam);
其中glpMyWnd是一个全局的CWnd指针,当相应的窗口没有打开时,实际上glpMyWnd->GetSafeHwnd()的结果为NULL。
这样实际上消息没有被处理,但是每次会消耗资源,发送多次(如100次)后资源明显减少,甚至可能会耗尽资源,如果关闭程序,则资源可以恢复正常,证明不是由于内存泄露造成。
如果我将代码修改为:
if (glpMyWnd->GetSafeHwnd())
::PostMessage(glpMyWnd->GetSafeHwnd(),UM_MY_MESSAGE,(WPARAM)wParam,(LPARAM)lParam);
即保证当glpMyWnd有效时才调用PostMessage()发送消息,则不会有问题。
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
但是我NEW了一个测试程序,试验这样的代码,却无法发现同样的情况
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
上述代码是在一个工作线程(Worker Thread)中,所以我在测试程序中也产生了一个线程,但是也没有问题
请问如何解释???

THANK A LOT FIRST!

可以发EMAIL给我: ecai@263.net
...全文
468 7 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
7 条回复
切换为时间正序
请发表友善的回复…
发表回复
ecai 2001-03-09
  • 打赏
  • 举报
回复
非常感谢大家的回答! (已经给分)

关于classfactory(void) 的回答,其实我也看了MSDN的,只是我没有考虑到worker-thread不自动产生消息队列.如果这样,使用UserInterface thread,由于它是自动产生消息队列,就应该不会有这个问题了

再次感谢!
ecai 2001-03-09
  • 打赏
  • 举报
回复
非常感谢大家的回答,有几点补充
1)关于classfactory(void) 的回答,其实我也看了MSDN的,只是我没有考虑到worker-thread不自动产生消息队列.如果这样,使用UserInterface thread,由于它是自动产生消息队列,就应该不会有这个问题了
2)关于发送给NULL窗口的消息时耗尽资源的问题
我写了一个测试程序,建立一个worker thread,然后在里面不断的PostMessage(NULL,....)10000次,没有发现资源减少,哪位有兴趣的话请测试一下,证明的确会有这样的问题
classfactory 2001-03-07
  • 打赏
  • 举报
回复

1、这种问题也值得问。

2、如果hWnd为NULL,则消息将发到当前线程,而不是“没有处理”。如果你的工作者线程有消息队列,则每个消息将加入消息队列,只有在使用GetMessage等调用时才移去一条。如果你的线程没有这样的调用,那么这些消息永远得不到处理,当然占用内存资源了!具体察看MSDN。这种东西不要想当然,有MSDN为什么不看呢?PostMessage函数又不是你写的。

Kevin_qing 2001-03-07
  • 打赏
  • 举报
回复
关注
In355Hz 2001-03-07
  • 打赏
  • 举报
回复
同意Gdj的看法:
尽管WindowProc是以Pascal方式调用的,但是用afx_msg void OnMyMessage();定义的函数却是按标准C方式调用的(afx_msg 宏什么也不扩展)标准C方式要求函数自己从栈中弹出参数。如果按1中的方法做的话,如Gdj所说,肯定会有问题(至少内存泄漏)
Gdj 2001-03-07
  • 打赏
  • 举报
回复
这和postmessage没关系。
相当于你定义了一个函数是没有参数的。而调用时却压入了两个参数,当然要报错了。
Gdj 2001-03-07
  • 打赏
  • 举报
回复
这和C的函数实现方式有关
C中函数调用时,是由调用方将参数压入堆栈,而由函数中负责将堆栈复原。
window处理消息时,调用你的函数前将参数压入堆栈,
你的函数return时没有处理的话不但会使堆栈占用变大,
而且还会在release出错(因为函数返回的地址也在堆栈中)。
debug因为加入了许多调试信息,有很多的内存是没用到的。堆栈也没有release下的紧凑,
所以一般不会报错。

你说如果入侵打印机需要何种墨水呢,Irongeek(译注:作者的网站)吗?好的,本文这里将向您讲述如何通过打印机以鲜为人知的方式来渗透网络。以前,除了垃圾箱中的复印件所带来的安全威胁外,并不会有其它太多的安全隐患。但现在的打印机却可通过网络与嵌入式操作系统、存储和IP协议栈相关联,已经不再像以前一样单一了。本文将就网络打印机泄漏用户、机主和网络的相关信息的话题展开讨论。 由于本文中关于攻击的内容多于防御,因此看起来有点像黑帽子。但是我觉得这些信息对于系统管理员和审计者来说更为有用,可以帮助他们在面对网络打印机时更清楚地知道该关注哪一方面的信息。关于如何锁住网络打印机,你可以访问厂商的官方网站以获取更多的建议。关于惠普网络打印机的一份指南在本文的底部已经附上下载连接,如果不出意外,本文将引领你在正确的方向上进行思考。 本文测试的打印机主要是基于Hewlett-Packard LaserJet 4100 MFP (Fax/Printer/Copier/Scanner),HP Jetdirect 170x和HP JetDirect 300X (J3263A),但与此同时我也将讲述一些关于Ricoh Savin打印机的内容,以便让你知道,其实并不是只有惠普的网络打印机才存在安全问题的。本文最初来源于Droop的Infonomicon TV项目,它如滚雪球一般,没有具体的方向。但我继续坚持着,并对其进行整理,还有其他朋友给予的附加内容和建议,才使得本文更为完善和更有价值。关于本文的最新版本可在以下链接找到:

16,548

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC相关问题讨论
社区管理员
  • 基础类社区
  • AIGC Browser
  • encoderlee
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

        VC/MFC社区版块或许是CSDN最“古老”的版块了,记忆之中,与CSDN的年龄几乎差不多。随着时间的推移,MFC技术渐渐的偏离了开发主流,若干年之后的今天,当我们面对着微软的这个经典之笔,内心充满着敬意,那些曾经的记忆,可以说代表着二十年前曾经的辉煌……
        向经典致敬,或许是老一代程序员内心里面难以释怀的感受。互联网大行其道的今天,我们期待着MFC技术能够恢复其曾经的辉煌,或许这个期待会永远成为一种“梦想”,或许一切皆有可能……
        我们希望这个版块可以很好的适配Web时代,期待更好的互联网技术能够使得MFC技术框架得以重现活力,……

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