VC++调试C语言程序,把函数调用改为直接执行其代码,为何导致不能调试?
我把别人的一个能够正常调试的Dll程序拿来修改。只修改一项:取消一个函数的调用。不调用了,直接执行其代码。这个函数叫做RegisterIMEClass,它的功能是注册四个...
我把别人的一个能够正常调试的Dll程序拿来修改。只修改一项:取消一个函数的调用。不调用了,直接执行其代码。
这个函数叫做RegisterIMEClass,它的功能是注册四个窗口类并建立4个窗口。
由于整个程序(由多文件组成)只有一个地方调用此函数,因此我觉得没有必要采用调用函数的方式,就把函数里的程序段直接代替原来的调用函数语句。
调用此函数的语句在Dll程序的入口函数DllMain的开头,见下图中划红线的语句:
被调用的函数参见下图:
取消调用方式了,就把该程序段中的形参hInstance都用实参g_hInst取代。
此外也取消函数申明。
原函数中的第一句(划红线的那句)“WNDCLASSEX wc;”定义了一个结构变量。
按规定,C语言的变量定义要放在函数开头,或者放到所有函数的前面作为全局变量。因此我把这条语句上移。
结果程序变成这样:
这个程序是个汉字输入方法,是个Dll,需要有个调用它的应用程序,一般选择记事本程序NOTEPAD.EXE来调试输入法Dll。
调试那个别人的程序时很正常:按F5以后记事本窗口跳出,选择此输入法后记事本窗口隐退,VC++回到前台,程序就从DllMain进入,到断点停下。
可是我这个改动后的程序,选择输入法后记事本仍然占据前台不肯隐退。这时按字母键的话,字母就出现在记事本上。这样就就无法调试。
现在把问题简化:只在路路通的程序中加一句废话(图中红线所示),结果也能造成不能调试。然后把这句废话删除,又能正常调试。是不是因为我在加入一句后漏了该做的一点事情?我在加进这句话之后做的事是:存盘、编译、链接、全部链接、按F5。我还需要做啥?
把这句废话改成g_hInst=hInstDLL;也不行。把这句话改成hInstDLL=hInstDLL;也不行。改成只有一个分号的空语句(连同后面的注释)倒是可以的。 展开
这个函数叫做RegisterIMEClass,它的功能是注册四个窗口类并建立4个窗口。
由于整个程序(由多文件组成)只有一个地方调用此函数,因此我觉得没有必要采用调用函数的方式,就把函数里的程序段直接代替原来的调用函数语句。
调用此函数的语句在Dll程序的入口函数DllMain的开头,见下图中划红线的语句:
被调用的函数参见下图:
取消调用方式了,就把该程序段中的形参hInstance都用实参g_hInst取代。
此外也取消函数申明。
原函数中的第一句(划红线的那句)“WNDCLASSEX wc;”定义了一个结构变量。
按规定,C语言的变量定义要放在函数开头,或者放到所有函数的前面作为全局变量。因此我把这条语句上移。
结果程序变成这样:
这个程序是个汉字输入方法,是个Dll,需要有个调用它的应用程序,一般选择记事本程序NOTEPAD.EXE来调试输入法Dll。
调试那个别人的程序时很正常:按F5以后记事本窗口跳出,选择此输入法后记事本窗口隐退,VC++回到前台,程序就从DllMain进入,到断点停下。
可是我这个改动后的程序,选择输入法后记事本仍然占据前台不肯隐退。这时按字母键的话,字母就出现在记事本上。这样就就无法调试。
现在把问题简化:只在路路通的程序中加一句废话(图中红线所示),结果也能造成不能调试。然后把这句废话删除,又能正常调试。是不是因为我在加入一句后漏了该做的一点事情?我在加进这句话之后做的事是:存盘、编译、链接、全部链接、按F5。我还需要做啥?
把这句废话改成g_hInst=hInstDLL;也不行。把这句话改成hInstDLL=hInstDLL;也不行。改成只有一个分号的空语句(连同后面的注释)倒是可以的。 展开
2个回答
展开全部
按照C语言逐条执行的原理,你用代码代替函数是没错的,我认为原因有以下2点:1.你的程序中有多处引用了该函数,你值替换了其中一个。2.你的函数中的某些变量是在原有库下声明的,你改变了函数的位置,在新的位置中不包含这些库函数,导致程序无法识别这些变量。
追问
程序中只有1处引用了该函数。再说,就算其它地方引用此函数,编译和链接也通不过。
什么叫“原有库”?
函数没有移动位置只是取消了。里面的程序段仍在原来所在的文件srf.c中,原来的库函数的包含语句仍在此文件开头,仍然有效。退一步说,如果程序无法识别这些变量,也无法通过编译和链接。
推荐律师服务:
若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询