几则GTK+开发技巧

 

l         使用gtk_idle_add实现异步signal

 

最近开发桌面模块时,遇到一个棘手的问题:向DirectFB的窗口管理器注册了顶层窗口改变的事件。当前顶层窗口切换时,窗口管理器回调我设置的回调函数,在回调函数中又要调用窗口管理器的函数,以获取顶层窗口的信息。整个过程是同步调用的,即直接调用函数,这会重入一个窗口管理器函数,造成死锁。

 

后来通过gtk_idle_add把同步操作转换成异步操作,解决了这个问题。在Window上, SendMessagePostMessage分别对应于同步和异步消息。而在GTK+中,它所有的signal都是同步,要实现异步的signal,最简单的办法就使用gtk_idle_add

 

l         使用gtk_quit_add释放资源。

 

在开发桌面模块时,遇到另外一个问题:在注销时,退出桌面,这时要释放一些资源,包括关闭一些GtkWidget。这些操作是在退出gtk主循环后处理的,关闭GtkWidget时,总是会会死掉。看样子,在此之前,GtkWidget已经被非正常关闭了。所谓非正常,是说资源被销毁了,但destroy函数并没有被调用。

 

后来发现,在退出主循环时,所有的GUI资源都被释放掉了,DirectFB已经销毁,之后再访问GUI资源,后果无法预料。这样的操作只能在主循环之退出前调用,要做到这一点,可以通过gtk_quit_add增加了一个释放函数,在退出主循环之前被自动调用。一切OK了。

 

l         调试用libtool生成的可执行文件。

 

libtool产生的可执行文件,分为两层,外层是一个脚本文件,内层才是ELF文件。ELF文件放在.lib目录中,在linux下,以.开头的文件都是隐藏的,所以正常情况下看不到。一般都通过脚本文件运行,脚本文件会处理共享库相关的一些设置,比如设置库的路径等等。

 

不知道内幕的新手,往往尝试用gdb去调试脚本文件,面对莫名其妙的错误束手无策。即使知道.lib下的文件才是真正的可执行文件,去调试那个ELF文件仍然很麻烦,你必须要手工去设置库的路径。

 

其实不用那么麻烦,脚本文件最终不是要执行真正的ELF文件吗?用vim打开那个文件,我们发现它调用exec去执行真正的ELF文件,把exec换成gdb,然后再运行这个脚本文件,不用其它任何设置,自动进入调试器。当然,你可以把这个文件拷贝一份,一个用于正常执行,一个用于调试执行。