0
Posted on 下午10:17:00 by Fan Zhang and filed under

  打开 Dev-C++,建立一个新的工程,添加一个新文件:

#include <gtk/gtk.h>

int main(int argc, char *argv[])
{
GtkWidget *window;
gtk_init(&argc, &argv);

window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
gtk_window_set_title(GTK_WINDOW(window), "Hello World");
gtk_widget_show(window);
gtk_main();

return 0 ;
}

  这个时候还不能编译,需要修改工程属性,在"工程->工程属性->参数" 或 "工具->编译选项"中的链接器框里面填入:

-lgtk-win32-2.0 -lgdk-win32-2.0 -latk-1.0 -lgdk_pixbuf-2.0 -lpangowin32-1.0 -lgdi32 -lpango-1.0 -lgobject-2.0 -lgmodule-2.0 -lglib-2.0 -lintl -liconv

在编译选项里面填入:

-mms-bitfields

就可以编译通过了。

  在运行以后,你会发现出现一个空白窗口,标题为 Hello World。这个时候只点击窗口的关闭是不能结束进程的,你要去任务管理器里面把进程结束。

  在工程属性里面,如果把工程类型设置为"Win32 控制台程序",则运行的时候会同时出现一个控制台窗口(一个黑色的命令行界面的窗口),这个窗口在调试的时候很有用,一些错误信息会在这里显示。如果把工程类型设置为"Win32 图形界面程序",这个黑窗口就没有了。

  为什么要在编译选项里面加入"-mms-bitfields"?下面照抄网上找来的解释:

  CPU访问内存时,总是以其整数字长为单位读写。比如 x86 CPU 总是从4字节的整数倍数地址上,读取4字节数据,它不能随心所欲地从任何位置开始读取任意长度数据。为了效率考虑,默认情况下编译器总是让整数存放于其长度的整数倍数地址上。在一个结构中,为了做到这一点,有时不得不浪费几个字节。

  举个例子,我们定义一个结构:

struct {
char c;
int i;
};

  从字面上看,这个结构的长度是5个字节,但默认情况下编译器总是分配8个字节,是为了让 i 出现在偏移量 4 地址上。

  位域 bitfields 是 C 语言结构中的一个成员,可以指定该成员所占内存的位数 bit。然而,在位域的对齐方式上,GCC和MSVC这2个编译器产生了巨大的分歧。现在,我们将上面这个结构改成下面这样子:

struct {
char c; int b: 1;
int i;
};

  我们在 c 和 i 中插入了一个只占 1 位内存的整数。在 GCC 中,我们测试该结构的长度,发现仍然是 8 个字节,就是说 b 利用了 c 和 i 间的空隙,而没有多占空间。然而在 VC 中我们会发现,结构长达 12 字节。也就是说 b 像其他所有整数一样,在4倍数地址上对齐了。

  如果仅仅这样还好办,不幸的是,如果你在b后面再插入一个位域 b2,长度还是12。而如果插入一个 short 型的位域,长度将变成16!

  其原因在于 VC 使用了一种古怪的对齐方式,且没有完整的文档描述。基本上,VC 将结构中相邻的相同数据结构位域组成位域组,然后每个位域组都默认要求按其数据类型对齐。另外还有许多不同的例外情况。这样的情况与任何一个普通 GCC 支持的 对齐模式都不同。对齐方式不同意味着什么呢?考虑一下,Windows 是用 VC 编译的,也就是说所有 Windows API 都使用 VC 对齐方式。而如果你用 MinGW GCC编译 Windows 程序,你对所有使用了位域的 Windows API 的调用都将出错!而我们的 GTK+ for Windows 显然也是使用了这种对齐方式。

  万幸的是,Windows 版 GCC 在编译时补上了一个新的命令行开关,-mms-bitfields,使其使用 VC 兼容的对齐方式。而这个开关别的平台上的 gcc 则都没有。加上这个编译开关后生成的代码将与 VC 的代码有相同的行为特征。

0
评论 : Hello Gtk+ ,最简单的GTK+程序

发表评论