| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 945 人关注过本帖
标题:把函数调用改为直接执行其代码,为何导致不能调试?
取消只看楼主 加入收藏
tm1mc2
Rank: 2
等 级:论坛游民
帖 子:28
专家分:46
注 册:2014-8-21
结帖率:50%
收藏
已结贴  问题点数:20 回复次数:6 
把函数调用改为直接执行其代码,为何导致不能调试?
我把别人的一个能够正常调试的Dll程序拿来修改。只修改一项:取消一个函数的调用。不调用了,直接执行其代码。
这个函数叫做RegisterIMEClass,它的功能是注册四个窗口类并建立4个窗口。
由于整个程序(由多文件组成)只有一个地方调用此函数,因此我觉得没有必要采用调用函数的方式,就把函数里的程序段直接代替原来的调用函数语句。
调用此函数的语句在Dll程序的入口函数DllMain的开头,见下图中划红线的语句:
图片附件: 游客没有浏览图片的权限,请 登录注册

被调用的函数参见下图:
图片附件: 游客没有浏览图片的权限,请 登录注册

取消调用方式了,就把该程序段中的形参hInstance都用实参g_hInst取代。
此外也取消函数申明。
原函数中的第一句(划红线的那句)“WNDCLASSEX wc;”定义了一个结构变量。
按规定,C语言的变量定义要放在函数开头,或者放到所有函数的前面作为全局变量。因此我把这条语句上移。
结果程序变成这样:
图片附件: 游客没有浏览图片的权限,请 登录注册

这个程序是个汉字输入方法,是个Dll,需要有个调用它的应用程序,一般选择记事本程序NOTEPAD.EXE来调试输入法Dll。
调试那个别人的程序时很正常:按F5以后记事本窗口跳出,选择此输入法后记事本窗口隐退,VC++回到前台,程序就从DllMain进入,到断点停下。
可是我这个改动后的程序,选择输入法后记事本仍然占据前台不肯隐退。这时按字母键的话,字母就出现在记事本上。这样就就无法调试。

想调试的朋友,到此下载程序:
http://www.
下载其中的“初中阶段示范程序”、拼音码表
如果你的系统是XP,就把下载的词库文件py.txt拷贝到:\WINDOWS\system32
建一个文件夹,把初中阶段示范程序《输入法编程入门标准程序.rar 》拷进去双击它,会释放出很多文件和文件夹。把其中的文件夹“说明”中的imm.h覆盖你的VC++的旧版本。
然后进入:Build->set Active Configuration,选中:srf-Win32 Release 。
然后选noteped.exe来调试本Dll。
做法是:
    Project->Settings->Debug->Executable for debug session
单击它下面右边的按钮,点击Browse...。对于windowsXP系统,它在C:\WINDOWS\NOTEPAD.EXE
设置好断点后,点击F5,VC就会打开记事本,在Windows的状态栏中选择“天下无敌”输入法,就可以像调试普通可执行程序一样调试这个输入法了。

[ 本帖最后由 tm1mc2 于 2014-9-28 11:20 编辑 ]
2014-09-28 11:03
tm1mc2
Rank: 2
等 级:论坛游民
帖 子:28
专家分:46
注 册:2014-8-21
收藏
得分:0 
现在把问题简化:只在路路通的程序中加一句废话(图中红线所示),结果也能造成不能调试。然后把这句废话删除,又能正常调试。
是不是因为我在加入一句后漏了该做的一点事情?
我在加进这句话之后做的事是:存盘、编译、链接、全部链接、按F5。我还需要做啥?
图片附件: 游客没有浏览图片的权限,请 登录注册
2014-09-29 17:38
tm1mc2
Rank: 2
等 级:论坛游民
帖 子:28
专家分:46
注 册:2014-8-21
收藏
得分:0 
把这句话改成g_hInst=hInstDLL;也不行。
把这句话改成hInstDLL=hInstDLL;也不行。
改成只有一个分号的空语句(连同后面的注释)倒是可以的。
2014-09-29 18:01
tm1mc2
Rank: 2
等 级:论坛游民
帖 子:28
专家分:46
注 册:2014-8-21
收藏
得分:0 
谢谢回答。
我去网上书店买了<windows核心编程>,并且到百度文库下载了该书的第19-21,讲动态链接库的部分。
    目前问题是这样:我把别人能够正常调试的程序拿来修改。4个窗口是他的不是我的,我没改,如果他的是独立线程那么我的就是,反之也然。能否正常调试跟是否独立线程无关。不过从我的水平上理解,这4个窗口不是线程。这4个窗口中1个是其余3个的父窗口。它们各有自己的消息处理程序。不过扯这些没用。反正他的能正常调试。
    我只是把一个函数改为直接执行,省去调用环节而已,这几个窗口一点都没改。DLL_THREAD_ATTACH消息的处理也没改。如果我的程序是因为“新线程状态dllmain返回DLL_THREAD_ATTACH从而直接跳过上面.”,那么他的程序为什么就不会“从而直接跳过上面.”?就不会“悲剧了”?
    问题应该出在我跟他的不同点上。但原先修改太多,不同点也太多,因此简化修改:只加一句无错的废话:https://bbs.bccn.net/thread-436751-1-1.html
    结果也不行。所以你上面说的哪些原因不对。那些原因在原来能调试的程序中都有,却能正常调试。
2014-09-30 16:25
tm1mc2
Rank: 2
等 级:论坛游民
帖 子:28
专家分:46
注 册:2014-8-21
收藏
得分:0 
请教如何把文件传给你?
2014-09-30 20:03
tm1mc2
Rank: 2
等 级:论坛游民
帖 子:28
专家分:46
注 册:2014-8-21
收藏
得分:0 
路路通的软件包:
输入法编程入门标准程序.rar (219.5 KB)

路路通的码表:
PY.zip (460.09 KB)


如果你的系统是XP,就把下载的词库文件py.txt拷贝到:\WINDOWS\system32。这件事最重要,否则程序运行时找不到码表会死机,甚至可能要重装系统
建一个文件夹,软件包拷进去双击它,会释放出很多文件和文件夹。把其中的文件夹“说明”中的imm.h覆盖你的VC++的旧版本中的同名文件。
然后进入:Build->set Active Configuration,选中:srf-Win32 Debug。
然后选noteped.exe来调试本Dll。
做法是:
Project->Settings->Debug->Executable for debug session
单击它下面右边的按钮,点击Browse...。对于windowsXP系统,它在C:\WINDOWS\NOTEPAD.EXE
设置好断点后,点击F5,VC就会打开记事本,在Windows的状态栏中选择你的输入法,就可以像调试普通可执行程序一样调试你的输入法了。

有点眉目了:
其它网站有人这样答复:
如果编译通过,debug是可以进断点的。
不能进断点本身应该是因为源码和实际动态库不一致
你可能有其他的程序加载了这个动态库,这样动态库就不能被替换。
所以,虽然编译通过了但是输入法对应的动态库还是之前的。
当你把代码改回去的时候源码和动态库一致就可以调试了。
实际上输入法对应的动态库从头到尾都没有变。
你可以看一下项目构建的完整输出,发出来好确认问题。还有工程的设置最好也贴一下。

我猜想他的意思是:
我用notepad.exe调试我的程序时,即使关闭那个调试的notpad窗口,或者按shift+F5退出调试,但是电脑上还有其他notepad窗口的话,那么“天下无敌”输入法仍然没有退出,因此下次再调试时系统就不会调用DllMain。

[ 本帖最后由 tm1mc2 于 2014-10-2 11:42 编辑 ]
2014-10-02 11:24
tm1mc2
Rank: 2
等 级:论坛游民
帖 子:28
专家分:46
注 册:2014-8-21
收藏
得分:0 
好吧该结帖了。
问题有点眉目了。
Dll进入后不易退出,因此修改编译后大概要重启才能调试。不过我记得以前有人解决过这类问题。我有空去找找看。
昨天电脑故障,今天又忙其它事。明后天估计可以把问题弄清楚。以后遇到问题再问吧。
2014-10-02 18:33
快速回复:把函数调用改为直接执行其代码,为何导致不能调试?
数据加载中...
 
   



关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.018822 second(s), 9 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved