免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 1333 | 回复: 0
打印 上一主题 下一主题

再转!! [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2006-10-04 08:37 |只看该作者 |倒序浏览

大家一起用gtk编程1(开始与热身)
大家一起用gtk编程1(开始与热身)
转载请注明出处:
http://lvjinhua.cublog.cn
作者:lvjinhua at gmail dot com
2006.09.20

  • 写在最前面
笔者写做本文的目的,主要是为初学GTK编程的新手们提供一个能够快速上手的学习档案,能够通过自己将所有的代码输入并编译,以达到学习的目的。同时,也希望它成为一个参考手册,希望GTK中的每一个API都能在本文中找到相应的示例。
笔者将尽力保证所有的代码都是最短小的,这样才能保证大家都有足够的动力去手工输入它。
由于笔者时间及精力有限,不能一次将所有内容呈现给所有读者,因此拟定了一个计划:每天更新一个章节的内容,在笔者的Blog上进行连载,同时会不断地对以前的内容进行修改和完善,因此为了保证大家能够读到最新的内容,请随时关注笔者的Blog:
http://lvjinhua.cublog.cn
起笔的日子:2006.09.20

  • 为什么是GTK?
为什么不是GTK?笔者不想花费太多的口水去辨证为什么选择GTK而不是其它的东西;任何技术都没有好坏之分,只有使用它的人有能力的强弱之别;笔者认为比较明智的做法是:多编些程序,少做些争论。

  • 1、GTK简介
GTK (GIMP Toolkit) 是一套用于创建图形用户界面的工具包。它遵循 LGPL 许可证,所以可以用它来开发开源软件、自由软件,甚至是封闭源代码的商业软件,而不用花费任何费用来购买许可证和使用权。当前,GTK已经被成功地应用到了大量的自由软件及商业软件中,已经取得了很大的成功。
GTK 的创建者:
    Peter Mattis: petm@xcf.berkeley.edu
    Spencer Kimball: spencer@xcf.berkeley.edu
    Josh MacDonald: jmacd@xcf.berkeley.edu
当前,GTK主要由几大组件构成:
*Gtk+:GTK的主要构件,包括所有的图形控件及大量实用的API。
*Glib:包含一些标准函数的替代函数,以及一些处理链表等数据结构的函数等。这些替代函数被用来增强GTK 的可移植性,同时提供 libc 的对应函数的增强版本。
*Pango:该组件用来处理国际化文字输出。

  • 2、预备
工欲xxx,必先利其器!在进行实际的程序设计之前,应该先明确一些主要的开发工具。
1)GTK是跨平台的,它能够运行于Linux/Unix/Windows/MacOS及嵌入式系统,但这不是本文所关注的重点;实际上,只要按照GTK所提供的API去编程,基本上在一个平台上设计的程序,在其它平台可以不加任何修改而成功地进行编译。
笔者使用的操作系统是:
Dubuntu-6.06
,本文中所有的示例代码将在该平台上进行开发并编译运行;当然,这并不代表不能使用其它操作系统,只要安装了GCC编译环境、GTK/Glib/Libc开发库,基本上就能成功地编译运行本文中的所有示例,现就Ubuntu Dapper 发行版GTK开发环境安装方法简述如下:
sudo apt-get install vim                        #是的,笔者使用vim来编写代码,当然您可以使用任何自己喜欢的编辑器
sudo apt-get install build-essential       #这将安装
gcc/g++/gdb/make 等基本编程工具
sudo apt-get install gnome-core-devel  #这将安装 libgtk2.0-dev libglib2.0-dev 等开发相关的库文件
sudo apt-get install pkg-config            #用于在编译GTK程序时自动找出头文件及库文件位置
sudo apt-get install devhelp                 #这将安装 devhelp GTK文档查看程序
sudo apt-get install libglib2.0-doc libgtk2.0-doc
                                                    #这将安装 gtk/glib 的API参考手册及其它帮助文档
sudo apt-get instal glade libglade2-dev #这将安装基于GTK的界面构造程序
当然,其它的 Linux 发行版可参考相应的文档进行开发环境的搭建,各大Linux论坛是个不错的咨询地:
www.linuxsir.org
,
www.linuxfans.org
如果有热心的同仁能提供其它操作系统 GTK 开发库的安装方法,欢迎提供给我笔者,笔者将在这里分享给大家!先行谢过了。

  • 3、Hello,Dubuntu!
嗯,早就急不可待了,让我们开始我们的第一个程序吧!
本程序的主要功能: 显示一个窗口,并在窗口的标题栏显示字符串"Hello, Dubuntu!"
源代码如下所示,编译成功后,可以通过命令行输入 ./hello_dubuntu 来运行此程序,显示效果如下:

hello_dubuntu.c
#include
/* 一般可以在 /usr/include/gtk-2.0 下找到上边的头文件
* 上边的头文件的作用是包含进行GTK编程所有可能用到的头
* 文件,包括glib.h等
*/
int
main(int argc, char *argv[])
{
        GtkWidget *window;
        // GtkWidget 是绝大部分可视组件的的基类
        gtk_init(&argc, &argv);
        //对程序传入的命令行参数进行标准化处理
        window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
        //创建窗口(200x200大小)
        gtk_window_set_title(GTK_WINDOW(window), "Hello,Dubuntu!");
        //设置窗口标题
        gtk_widget_show(window);
        //显示窗口
        gtk_main();
        //Gtk程序主循环
        return 0;
}
编译程序: gcc hello_dubuntu.c -o hello_dubuntu `pkg-config --cflags --libs gtk+-2.0`  # 注意:"`" 不是普通的单引号 "'",而是同"~"在一起的那个符号!
是的,上边的程序非常简单,除了注释就没几条语句了!但它确实是一个GTK程序,虽然它还不够完善,缺少信号处理,因此当您单击“关闭”按钮关闭此窗口后,实际上程序还在运行。
1) 编译程序的命令行:
如上,使用GNU C语言编译器 gcc , 其中 pkg-config --cflags --libs gtk+-2.0 用于生成 gcc 编译及链接程序时所必须的头文件及库文件列表,在笔者的机器上运行该命令得到的结果如下:
命令: pkg-config --cflags --libs gtk+-2.0
输出:
-I/usr/include/gtk-2.0 -I/usr/lib/gtk-2.0/include -I/usr/include/atk-1.0 -I/usr/include/cairo -I/usr/include/pango-1.0 -I/usr/include/glib-2.0 -I/usr/lib/glib-2.0/include  -lgtk-x11-2.0 -lgdk-x11-2.0 -latk-1.0 -lgdk_pixbuf-2.0 -lm -lpangocairo-1.0 -lfontconfig -lXext -lXrender -lXinerama -lXi -lXrandr -lXcursor -lXfixes -lpango-1.0 -lcairo -lX11 -lgobject-2.0 -lgmodule-2.0 -ldl -lglib-2.0
2) 大家如果对某个GTK标准API定义,或者某个类型/常量定义不清楚,可以在 devhelp 帮助程序中进行搜索,以查看某参数说明。
3) gtk_init(&argc, &argv) 函数用于对传入进来的标准命令行参数进行解析并处理,这些标准命令行参数为(即:运行我们的程序时,通过命令行传入的下列参数会被自动处理):
  • --gtk-module
  • --g-fatal-warnings
  • --gtk-debug
  • --gtk-no-debug
  • --gdk-debug
  • --gdk-no-debug
  • --display
  • --sync
  • --name
  • --class4) gtk_widget_show(window) 用于告诉程序, 我们的 window 构件已经准备完成,可以显示了。
    5) gtk_main() ,程序将会运行到此,然后等待“事件”的发生;当有事件发生后,将调用此事件对应的回调函数,当回调函数执行完毕,又会重新回到 gtk_main() ,等待新的“事件”发生。
    6) 宏 GTK_WINDOW(window) 是用于进行类型检查及转换,它将把一个可以转化为 GtkWindow 的构件强制转换为GtkWindow 类型后传递给函数。
    好了,hello_dubuntu.c 理解了吗? 什么!没有理解! 不要紧,我们下边还会有很多这样的小例子,再多输入几个就会理解了,相信我!
    下集预告:将在窗口中添加一个按钮,并为按钮关联"clicked"事件,以使单击按钮后会有一些返回


    大家一起用gtk编程2(添加按钮和连接事件)
    大家一起用gtk编程2(添加按钮和连接事件)
    转载请注明出处:
    http://lvjinhua.cublog.cn
    作者:lvjinhua at gmail dot com
    2006.09.20
  • 4、加入按钮和事件处理函数上回说道,咱们使用GTK创建了一个最简单的GTK程序,简单到只能显示一个200x200点大小的空白窗口,并在标题栏显示“Hello,Dubuntu!”的字样! 虽然简单,但确实是个不错的开端,好了,咱们现在在窗口中添加一个按钮。
    运行效果:

    代码:
    hello_dubuntu2.c
    /* 本例的主要目的是在窗口中显示一个按钮,
    * 并且单击按钮退出程序
    */
    #include
    void
    cb_button(GtkWidget *widget, gpointer data)
    {// 按钮"button"的回调函数
            gtk_main_quit();
    }
    int
    main(int argc, char *argv[])
    {
            GtkWidget *main_window; //主窗口对象
            GtkWidget *button;              //将要放置到主窗口中的按钮对象
            gtk_init(&argc, &argv);
            main_window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
            gtk_window_set_title(GTK_WINDOW(main_window), "Hello,Dubuntu2!");
            //设置窗口的默认大小(宽200,高度50)
            gtk_window_set_default_size(GTK_WINDOW(main_window), 200,50);
            button = gtk_button_new_with_label("退出程序");
            gtk_container_add(GTK_CONTAINER(main_window), button);
            //为"button"连接“单击事件”要调用的回调函数
            g_signal_connect(G_OBJECT(button), "clicked", G_CALLBACK(cb_button),NULL);
            gtk_widget_show(button);
            gtk_widget_show(main_window);
            //上边的两句可以合为 gtk_widget_show_all(window)
            gtk_main();
            return 0;
    }

    编译: gcc -o hello_dubuntu2  hello_dubuntu2.c  `pkg-config --cflags --libs gtk+-2.0`
    程序注释:
    1)在GTK中,默认添加到窗口中的控件会自动占满所有的空间,因此当我们的程序运行时,将窗口放大时按钮也跟着放大了;这点同Windows及Qt是不相同的。正因为如此,在GTK控件库中有几个控件专门用来进行窗口布局,比如说vbox, hbox, table, GtkPixed 等, 通过对它们的灵活操作,可以得到一个非常漂亮的应用程序界面!这将在以后进行详细介绍。
    2)关于事件与回调函数
    事件:GTK同许多其它的图形编程库相似,都采用事件驱动方式来工作,这就关系到出现什么事件做什么工作的问题。(在GTK中还有个“信号”的概念,同“事件”的概念不容易分清楚,特别是刚开始学习时,不过没关系,初期我们就把它们当一个概念来理解),在GTK2.0中,一般使用 g_signal_connect() 函数来注册每个对象和其对应的处理函数,如本例所示。
    回调函数:实际上就是一个普通的函数,不过它并不会被显示地直接调用,而是把它的地址注册到另一个函数,在那个函数中间接地对它进行调用,这也是回调的由来。
    3)在本例中,我们通过下列语句为“button”注册了一个"clicked"事件的回调函数“cb_button",前缀”cb“即”call back(回调)”的意思。
    g_signal_connect(G_OBJECT(button), "clicked", G_CALLBACK(cb_button),NULL);
    由于注册了上边的回调函数,因此当我们用鼠标单击按钮时,就会激发按钮的“clicked”事件,因此会调用 cb_button() 函数,而此函数中的语句  gtk_main_quit() 的作用是退出程序,因此我们单击按钮后整个程序就会退出。
    4)当然,这个程序还有个小“bug”,即直接单击右上角的“关闭按钮”关闭程序后,虽然主窗口消失了,但程序并没有直接地退出,还驻留在内存中。 这是因为当单击右上角的“关闭按钮”关闭程序后,会产生“destroy”信号,而我们并没有为此信号使用 g_signal_connect() 函数注册相关的处理函数,因此它的行为并不是我们所期望的;解决方法就是为主窗口的”destroy"信号注册一个回调函数,并在此回调函数中调用 gtk_main_quit() 以便退出程序,将如下代码添加到hello_dubuntu2.c 的 gtk_main() 函数调用的上边就行:
    g_signal_connect(G_OBJECT(main_window), "destroy", G_CALLBACK(cb_button),NULL); 请注意:在这里我们再一次使用了 "cb_button“函数,这是因为它的行为正是我们想要的,即”调用此回调函数后, 退出程序“。
    好了,今天的内容差不多了,很多内容都没有深入研究,不过没关系,慢慢来,以后将要以专题的形式对GTK的每个部件及API进行深入并细致的说明。如果您对本例中的一些概念没有完全理解也没有关系,继续下一步,很容易理解的!千万不要呆在原地不动。
    下回预告:将简要说明如何编写简单的 Makefile 文件来组织我们的源程序,另外还将介绍如何利用 gdb 对我们的程序进行调试!精彩不容错过。
    附:添加”destroy“信号处理后的 hello_dubuntu2.c
    hello_dubuntu2.c
    /* 本例的主要目的是在窗口中显示一个按钮,
    * 并且单击按钮退出程序
    */
    #include
    void
    cb_button(GtkWidget *widget, gpointer data)
    {// 按钮"button"的回调函数
            gtk_main_quit();
    }
    int
    main(int argc, char *argv[])
    {
            GtkWidget *main_window; //主窗口对象
            GtkWidget *button;              //将要放置到主窗口中的按钮对象
            gtk_init(&argc, &argv);
            main_window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
            gtk_window_set_title(GTK_WINDOW(main_window), "Hello,Dubuntu2!");
            //设置窗口的默认大小(宽200,高度50)
            gtk_window_set_default_size(GTK_WINDOW(main_window), 200,50);
            button = gtk_button_new_with_label("退出程序");
            gtk_container_add(GTK_CONTAINER(main_window), button);
            //为"button"连接“单击事件”要调用的回调函数
            g_signal_connect(G_OBJECT(button), "clicked", G_CALLBACK(cb_button),NULL);
            gtk_widget_show(button);
            gtk_widget_show(main_window);
            //上边的两句可以合为 gtk_widget_show_all(window)
            g_signal_connect(G_OBJECT(main_window), "destroy", G_CALLBACK(cb_button),NULL);
            gtk_main();
            return 0;
    }

    编译: gcc -o hello_dubuntu2  hello_dubuntu2.c  `pkg-config --cflags --libs gtk+-2.0`


    大家一起用gtk编程3(初步使用Makefile)
    大家一起用gtk编程3(初步使用Makefile)
    转载请注明出处:
    http://lvjinhua.cublog.cn
    作者:lvjinhua at gmail dot com
    2006.09.20
  • 5、初步使用Makefile上回说道,咱们使用GTK创建了一个能够截获事件的GTK程序,本节将简单地介绍一下如何使用Makefile来组织我们的源程序,使用Makefile是基于如下几个原因:

    • 能实现从无限简单到无穷复杂的软件工程组织
    • 能方便地与众多的Linux命令与实用程序集成,当然也包括Vim与emacs
    • 还有很多,就留给读者自己探索吧...
    笔者在这里介绍Makefile的主要目的是想让大家知道Linux下有这样一个工具,使用它确实很方便,并且希望大家在有需要的时候能够想到它。
    总的来说,Makefile是使用一系列的依赖关系和时间值,来决定是否对一个目标进行重构建;不废话了,来看看我们的Makefile文件长什么样:
    Makefile
    注意:Makefile 文件如果从网页上直接拷贝,往往不能成功正常使用,请从下边的附件中下载可用的文件。
    CC=gcc
    PROG_NAME=hello_dubuntu2
    INCS=
    SRCS=hello_dubuntu2.c
    #从xx.c 文件得到 xx.o 文件
    OBJS=${SRCS:.c=.o}
    #编译GTK程序时要用到的库
    LIBS=gtk+-2.0
    #---- 用户修改区域 结束
    # -O2
    CFLAGS=`pkg-config --cflags ${LIBS}` -g -Wall
    LDFLAGS=`pkg-config --libs ${LIBS}`   -g -Wall
    all: ${PROG_NAME}
    ${PROG_NAME}:${OBJS}
            ${CC} -o ${PROG_NAME} ${OBJS} ${LDFLAGS}
    #注意:上边”${CC}" 的前边有一个TAB键,而不是空格
    #如果有头文件进行修改,则自动编译源文件
    ${OBJS}:${INCS}
    .c.o:
            ${CC} -c $
    编译:将此Makefile文件与上一节的 hello_dubuntu2.c 文件放在同一个文件夹下,然后运行如下命令即可编译出 hello_dubuntu2 可执行文件:
    make

    文件:
    hello_dubuntu.tar
    大小:
    10KB
    下载:
    下载
    程序注释:
    1)刚开始的几行定义了几个变量,比如用CC来代替真正的 gcc 编译器,这样当想换别的编译器来编译我们的程序时直接改变CC变量的值就OK了。其它的:

    • CC 指代用来编译程序的编译器,这里使用 gcc
    • RPOG_NAME 指代最终要生成的可执行文件名,需手工填入
    • INCS 指代工程文件中所自定义的所有头文件,需手工填入
    • SRCS 指代所有使用到的源文件,需手工填入
    • OBJS 是通过 .c 文件得到的 .o 文件,因为每个 .c 文件都将编译生成一个对应的 .o 文件,自动生成
    • LIBS 用来指代编译GTK程序时需要使用到的GTK相关库,一般使用默认的 gtk+-2.0 即可,需手工填入
    • CFLAGS 用来指代编译程序时使用到的一些编译选项, -g 表示生成调试信息以供GDB使用,-Wall表示生成编译时的警告信息(W表示Warning,all 表示全部)
    • LDFLAGS 用来指代进行程序连接时使用到的一些选项

    以上这些变量,将在Makefile的剩余部分使用 ${xxx} 的形式进行引用。
    2)关于“目标”:“依赖关系”
    从“all: ${PROG_NAME}”这一句开始,Makefile就开始使用 目标:依赖 的关系来处理真正的程序编译了;而它们下边以 TAB 键开始的行就是满足依赖关系后要运行的程序(注意:是TAB键,不是空格)。具体笔者就不详细描述了,有兴趣的读者可以参考下边推荐的教程。
    3)关于 “.c.o:” 语句:
    这句话的意思就是说,当遇到一个 .c 文件,那么使用它下边的命令“         ${CC} -c $

    大家一起用gtk编程4(使用GDB调试程序)
    大家一起用gtk编程4(使用GDB调试程序)
    转载请注明出处:
    http://lvjinhua.cublog.cn
    作者:lvjinhua at gmail dot com
    2006.09.23
  • 6、使用GDB调试程序上回话说使用Makefile来组织源代码,这回简单地介绍下如何使用GDB来调试我们的程序;关于GDB的其它应用将在后续的章节中逐渐深入。
    首先需要肯定一点,GDB是个功能异常强大的调试工具,其本身只能运行于字符模式,但是当前众多基于GUI的调试器/IDE,无论是自由软件还是商业软件,绝大多数都使用GDB作为其后端(但这些基于GUI的调试器都不太稳定),因此GDB是个不二的选择(笔者推荐的GUI调试器:insight和ddd)。
    这里使用 hello_gdb.c 作为例子,如果你从前面一直看过来,对这个程序一定不会陌生,hello_gdb.c 主要在 hello_dubuntu2.c 的基础上,添加了几个整型和字符串型变量,来演示gdb的一些基本功能:
    运行效果图:

    hello_gdb.c
    /* 本例的主要目的是在窗口中显示一个按钮,
    * 单击按钮退出程序,并构建几个变量来演示GDB功能。
    */
    #include
    void
    cb_button(GtkWidget *widget, gpointer data)
    {// 按钮"button"的回调函数
            gint i=5;
            gint j=++i;
            gtk_main_quit();
    }
    //此函数用于演示GDB直接调用被调试程序的函数
    gint
    gdb_test(gint arg)
    {
            g_print("arg=%d\n",arg);
            arg++;
            return arg;
    }
    int
    main(int argc, char *argv[])
    {
            GtkWidget *main_window; //主窗口对象
            GtkWidget *button;              //将要放置到主窗口中的按钮对象
            //构造两个变量用于演示GDB功能
            gint a=5;
            gchar *name="Dubuntu-6.06";
            //
            gtk_init(&argc, &argv);
            main_window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
            gtk_window_set_title(GTK_WINDOW(main_window), "Hello,Dubuntu2!");
            //设置窗口的默认大小(宽200,高度50)
            gtk_window_set_default_size(GTK_WINDOW(main_window), 200,50);
            button = gtk_button_new_with_label("退出程序");
            gtk_container_add(GTK_CONTAINER(main_window), button);
            //为"button"连接“单击事件”要调用的回调函数
            g_signal_connect(G_OBJECT(button), "clicked", G_CALLBACK(cb_button),NULL);
            gtk_widget_show(button);
            gtk_widget_show(main_window);
            //上边的两句可以合为 gtk_widget_show_all(window)
            g_signal_connect(G_OBJECT(main_window), "destroy", G_CALLBACK(cb_button),NULL);
            gtk_main();
            return 0;
    }

    编译:  gcc -g -Wall -o hello_gdb hello_gdb.c `pkg-config --cflags --libs gtk+-2.0`
    注意:-g 参数用于为可执行文件生成调试信息;
             -Wall 用于在编译程序时打印所有的警告信息
    好了,程序就是上边这个(hello_gdb.c),我们使用如下的命令对它进行编译:
    gcc -g -Wall -o hello_gdb hello_gdb.c `pkg-config --cflags --libs gtk+-2.0`
    编译完后,如果没有错误,将生成 hello_gdb 可执行文件,此可执行文件将携带 gdb 调试时所需要的调试信息,有了这些调试消息,我们就可以在调试程序的时候查看函数名,变量名,源代码。
    好了,开始调试吧:
    1)在命令行下,通过如下命令加载刚编译生成的 hello_gdb 程序:
    gdb  ./hello_gdb
    加载成功后,将得到如下提示信息,并进入 gdb 的命令行模式:
    dubuntu@dubuntu:~/Desktop/gnome-gtk-prog/hello_gtk/src$ gdb ./hello_gdb
    GNU gdb 6.5.50.20060605-cvs
    Copyright (C) 2006 Free Software Foundation, Inc.
    GDB is free software, covered by the GNU General Public License, and you are
    welcome to change it and/or distribute copies of it under certain conditions.
    Type "show copying" to see the conditions.
    There is absolutely no warranty for GDB.  Type "show warranty" for details.
    This GDB was configured as "i686-pc-linux-gnu"...Using host libthread_db library "/lib/tls/i686/cmov/libthread_db.so.1".
    (gdb)
    2)好,现在已经成功启动gdb并且加载了可执行程序 hello_gdb,接下来的命令绝大部分都是争对 hello_gdb 程序,下面将列举几个最常用的命令:
    小技巧:在gdb命令中,只需要输入命令或参数的前几个字符,再按键盘上的“TAB”键,那gdb将自动补齐命令或参数,如果有多个候选者,那么gdb将把它们都列举出来。

    • list :简记为 l ,其作用就是列出程序的源代码,默认每次显示10行。


    • list 行号:将显示当前文件以“行号”为中心的前后10行代码,如:list 12
    • list 函数名:将显示“函数名”所在函数的源代码,如:list main
    • list :不带参数,将接着上一次 list 命令的,输出下边的内容。

    注意:如果运行list 命令得到类似如下的打印,那是因为在编译程序时没有加入 -g 选项:
    (gdb) list
    1       ../sysdeps/i386/elf/start.S: No such file or directory.
            in ../sysdeps/i386/elf/start.S

    • run:简记为 r ,其作用是运行程序,当遇到断点后,程序会在断点处停止运行,等待用户输入下一步的命令。
    • set args:设置运行程序时的命令行参数,如:set args 33 55
    • show args:显示命令行参数
    • continue:简讯为 c ,其作用是继续运行被断点中断的程序。
    • break:为程序设置断点。


    • break 行号:在当前文件的“行号”处设置断点,如:break  33
    • break 函数名:在用户定义的函数“函数名”处设置断点,如:break cb_button
    • info breakpoints:显示当前程序的断点设置情况
    • disable breakpoints Num:关闭断点“Num”,使其无效,其中“Num”为 info breakpoints 中显示的对应值
    • enable breakpoints Num:打开断点“Num”,使其重新生效


    • step:简记为 s ,单步跟踪程序,当遇到函数调用时,则进入此函数体(一般只进入用户自定义函数)。
    • next:简记为 n,单步跟踪程序,当遇到函数调用时,也不进入此函数体;此命令同 step 的主要区别是,step 遇到用户自定义的函数,将步进到函数中去运行,而 next 则直接调用函数,不会进入到函数体内。
    • until:当你厌倦了在一个循环体内单步跟踪时,这个命令可以运行程序直到退出循环体。
      finish:运行程序,直到当前函数完成返回,并打印函数返回时的堆栈地址和返回值及参数值等信息。
      stepi或nexti:单步跟踪一些机器指令。
    • print 表达式:简记为 p ,其中“表达式”可以是任何当前正在被测试程序的有效表达式,比如当前正在调试C语言的程序,那么“表达式”可以是任何C语言的有效表达式,包括数字,变量甚至是函数调用。


    • print a:将显示整数 a 的值
    • print ++a:将把 a 中的值加1,并显示出来
    • print name:将显示字符串 name 的值
    • print gdb_test(22):将以整数22作为参数调用 gdb_test() 函数
    • print gdb_test(a):将以变量 a 作为参数调用 gdb_test() 函数


    • bt:显示当前程序的函数调用堆栈。
    • display 表达式:在单步运行时将非常有用,使用display命令设置一个表达式后,它将在每次单步进行指令后,紧接着输出被设置的表达式及值。如: display a
    • watch 表达式:设置一个监视点,一旦被监视的“表达式”的值改变,gdb将强行终止正在被调试的程序。如: watch a
    • kill:将强行终止当前正在调试的程序
    • help 命令:help 命令将显示“命令”的常用帮助信息
    • call 函数(参数):调用“函数”,并传递“参数”,如:call  gdb_test(55)
    • layout:用于分割窗口,可以一边查看代码,一边测试:


    • layout src:显示源代码窗口
    • layout asm:显示反汇编窗口
    • layout regs:显示源代码/反汇编和CPU寄存器窗口
    • layout split:显示源代码和反汇编窗口
    • Ctrl + L:刷新窗口


    • quit:简记为 q ,退出gdb
    当然,gdb的功能远不止这些,包括多进程/多线程/信号/远程调试等功能在这里均没有提及,有需要的读者可以参考其它信息,本文的后续章节也将涉及一些内容。
    推荐阅读:
    用gdb调试程序
    3)调试实例:
    gdb ./hello_gdb           #启动gdb并载入被调试程序
    list gdb_test                #显示函数 gdb_test 的代码
    break cb_button         #在函数 cb_button 处设置断点
    info breakpoints         #显示所有断点信息
    enable breakpoints     #启动所有断点
    run                              # 开始运行程序
    #注:现在程序正常运行,当单击按钮“退出程序”后,将在函数“cb_button”处停止,因为这里被设置了一个断点
    bt                                #显示当前的函数调用堆栈
    display j                      #对变量 j 进行监视
    next                            #运行下一条指令
    print j                         #显示j的值
    print gdb_test(j)         #调用函数 gdb_test 并使用 j 作为参数
    call  gdb_test(++j)     #同上
    next
    finish                          #退出函数 cb_button
    continue                     #继续运行完程序
    quit                             # 退出gdb
    下集预告: 下节将简单地介绍如何使用 vbox/hbox 进行窗口布局,这样就能解决当前一个按钮占满整个窗体的问题了。


    本文来自ChinaUnix博客,如果查看原文请点:http://blog.chinaunix.net/u/14140/showart_179777.html
  • 您需要登录后才可以回帖 登录 | 注册

    本版积分规则 发表回复

      

    北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
    未成年举报专区
    中国互联网协会会员  联系我们:huangweiwei@itpub.net
    感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

    清除 Cookies - ChinaUnix - Archiver - WAP - TOP