GTK代码看不懂GSEAL宏
Gtk代码里面出现很多 GSEAL。比如状态栏控件的定义:
struct _GtkStatusbar
{
GtkHBox parent_widget;
GtkWidget *GSEAL (frame);
GtkWidget *GSEAL (label);
GSList *GSEAL (messages);
GSList *GSEAL (keys);
guint GSEAL (seq_context_id);
guint GSEAL (seq_message_id);
GdkWindow *GSEAL (grip_window);
guint GSEAL (has_resize_grip) : 1;
};
这个 GSEAL 我在gdkconfig.h 里面找到了定义:
#ifndef GSEAL
/* introduce GSEAL() here for all of Gdk and Gtk+ without the need to modify GLib */
#ifdef GSEAL_ENABLE
# define GSEAL(ident) _g_sealed__ ## ident
#else
# define GSEAL(ident) ident
#endif
#endif /* !GSEAL */
请教下这里的: _g_sealed__ ## ident 是什么意思,谢谢。 我记得##是连接符,也就是说GSEAL (frame) => _g_sealed__frame 看代码时这个宏可以忽略,因为这是gtk+开发内部事情,和应用开发没有太多关系。
在早期的gtk+开发中,对一些widget的封装写得不好,直接将GtkFoo的内部结构体暴露在了头文件中,导致一些应用开发者滥写代码,去直接存取了这些本应该封装在Object(类)部的私有数据--这就相当于直接存取了C++对象内部的私有属性(这在C++中是不可能的,但在这里发生了,因为这些代码没写好),这在当时可能不会有问题,但是如果有一天gtk+的那个Object(类)如果修改了这个结构体,应用程序的代码将不能正常工作。
为了避免这个现象的发生,现在gtk+开发者使用了这样一个宏GSEAL来标记了那些应该从头(.h)文件中移动到priv中的变量,最终应该把这些变量移动到priv(.c文件)中。举个例子:
像gtkstatusbar.h中对GtkStatusbar的结构定义如下:
struct _GtkStatusbar
{
GtkHBox parent_widget;
GtkWidget *GSEAL (frame);
GtkWidget *GSEAL (label);
GSList *GSEAL (messages);
GSList *GSEAL (keys);
guint GSEAL (seq_context_id);
guint GSEAL (seq_message_id);
GdkWindow *GSEAL (grip_window);
guint GSEAL (has_resize_grip) : 1;
};
这里边用GSEAL宏标记的变量应该被移到gtkstatusbar.c文件中的priv结构体中去定义,修改后的代码应该像这样:
cat gtkstatus.h
...
struct _GtkStatusbar
{
GtkHBox parent_widget;
/*< private >*/
GtkStatusbarPrivate *GSEAL (priv);
};
...
cat gtkstatus.c
struct _GtkStatusbarPrivate
{
GtkWidget *frame;
GtkWidget *label;
GSList *messages;
GSList *keys;
guint seq_context_id;
guint seq_message_id;
GdkWindow *grip_window;
guint has_resize_grip : 1;
}
...
这是他们在标记要做的工作,以后可能会对代码做这样的修改。
至于现阶段应用程序直接存取header文件中那些被GSEAL宏标记的私有变量时是在编译或运行时产生警告还是什么都不做就不清楚了,没有研究过。以后写代码是不能直接去操作那些私有变量的--因为没准有一天你的代码就不能编译或运行的。
GDK的情况跟上面的gtk+所说的是一样的。
以上只是个人的一点理解,如果不正确,可以再讨论。
这有一个邮件,提到了这个事情,可以看一下:
http://mail.gnome.org/archives/gtk-devel-list/2008-June/msg00014.html 谢谢两位。
我用的 gtk+-2.22.1 直接使用header文件中那些被GSEAL宏标记的私有变量,没有警告。
不能直接去操作那些私有变量才是合理的。
页:
[1]