GNUstep 下的编程—简介
本文介绍了 GNUstep 开发。它指导读者完成安装 GNUstep 和开发小型应用程序的过程。本文使用了 Objective-C 语言,它是 ANSI C 的真正面向对象的超集。它的语法简单、明确且易于学习。
OpenStep 由 NeXT Computer, Inc. 于 1994 年提出,作为开放标准,是高级面向对象 API 的集合,旨在使用 Objective-C 语言快速开发应用程序。它旨在独立于计算机的操作系统实现。为此,存在 Mach、Microsoft Windows(NT 和 95)、Sun Solaris 和 HP-UX 标准的实现。
在 1990 年代初期,GNUstep 诞生了,它是 OpenStep 标准的免费实现。GNUstep 旨在成为完全兼容 OpenStep 的实现,支持广泛的操作系统,同时完全免费。GNUstep 在 LGPL 许可条款下发布。GNUstep 目前在 Linux、Solaris 和大多数 BSD 上运行良好,并且初步支持 Microsoft Windows。
正如当时广泛报道的那样,Apple 于 1996 年收购了 NeXT。现在,借助 Mac OS X,Apple 正在推进 Cocoa,它是 OpenStep API 的扩展。在创建 Cocoa 时,Apple 添加了丰富 API 的新类。GNUstep 正在部分支持这些新功能,并且每天都在添加更好的支持。
GNUstep 还提供了用户界面类(应用程序套件的一部分)和底层窗口系统之间明确的分离。这一层称为 gnustep-back,为各种窗口系统提供实现,使 gnustep-gui 能够在各种后端下正常工作。目前正在为 X Window System、Microsoft Windows 和 Ghostscript 开发后端。图 1 显示了 GNUstep 的不同层。

图 1. GNUstep 的不同层
GNUstep 还提供与其他语言的绑定,例如 Java(使用 JIGS)和 Ruby(使用 RIGS),允许开发人员使用这些语言创建应用程序。此外,GNUstep 通过 StepTalk 提供强大的脚本功能,允许您使用 Smalltalk 创建可脚本化的应用程序或服务器。最后,GNUstep 提供了一个扩展,以便 Guile(Scheme 的一个版本)可以用作脚本语言。
为了在 Linux 下编译 GNUstep,需要安装以下程序和库(带有头文件)(指示的版本或更高版本):GNU make 3.75、GNU libc 2.1.2、GNU gcc 3.0.3、XFree86 4.1、ffcall 1.8、OpenSSL 0.9.6c(不是必需的,但推荐)、libtiff 3.5.5 和 libxml 2.2.3。
一旦满足所有这些要求,您现在就可以下载和编译 GNUstep。我们将安装 GNUstep 的不稳定版本,因为最近添加了值得使用和提及的新功能,尤其是在 Gorm(图形对象关系建模器)方面。Gorm 是 OpenStep 出色的界面构建器应用程序的克隆。Gorm 允许开发人员从标准对象调色板快速创建用户界面。
从 GNUstep 网站获取以下版本:GNUstep make 1.5.1、GNUstep base 1.5.1、GNUstep gui 0.8.3、GNUstep back 0.8.3 和 Gorm 0.2.0。
下载这些版本后,您就可以安装 GNUstep 了。您必须首先安装 GNUstep make、base、gui,最后安装 back。仔细查看每个版本的 INSTALL 文件以获取安装说明。有关安装 GNUstep 的详细说明,请参阅 GNUstep Unix 系统构建指南(请参阅资源)。
编译并安装 GNUstep 后,通过执行 shell 脚本加载适当的环境变量集(如有必要,调整路径)。
Bash 用户将输入
# . /usr/GNUstep/System/Makefiles/GNUstep.sh
C-shell 用户将输入
# . /usr/GNUstep/System/Makefiles/GNUstep.csh要编译和安装 Gorm,只需解压缩文件并键入(作为 root 用户)
# cd Gorm # make # make install
现在 GNUstep 和 Gorm 已经编译并安装完成,您可以开发您的小型应用程序,一个简单的 TIFF 图像查看器。此应用程序将使用模型-视图-控制器 (MVC) 设计。MVC 设计模式将软件组件分为三个部分:模型、视图和控制器。图 2 显示了 MVC 模式在我们的小型应用程序中的使用方式。
在 GNUstep 下,使用 Gorm 创建应用程序的视图。此应用程序允许您创建应用程序的用户界面。创建完成后,用户界面将作为存档文件(包含序列化的对象图)保存在其自己的子目录中。要启动 Gorm,只需键入
# openapp Gorm.app
Gorm 启动后,通过单击“工具”菜单中的“检查器...”和“调色板...”菜单项来显示“检查器”和“调色板”窗口。现在,通过单击“文档”菜单中的“新建应用程序”菜单项来创建新应用程序。完成这些步骤后,您的桌面应如图 3 所示。
让我们检查图 3 以解释不同的元素。表 1 显示了不同的元素及其角色。
从“调色板”窗口中,将 NSImageView 对象拖动到空窗口(“我的窗口”)并放下。图 4 显示了代表 NSImageView 对象的图标。

图 4. NSImageView 对象
现在,单击窗口中的 NSImageView,检查器窗口将自行更新,以便您可以为此对象设置正确的属性。将边框设置为“线边框”,将缩放设置为“适合”。NSImageView 属性的“检查器”窗口应如图 5 所示。
现在,从“检查器”窗口中,从顶部的组合框中选择“大小”项,以设置 NSImageView 对象的自动调整大小属性。将自动调整大小属性设置为 NSImageView 将允许对象在用户调整窗口大小时正确调整大小。通过单击“自动调整大小”框内的线条来设置参数,使其看起来像图 6 中的那样。
接下来设置窗口属性。单击“文件”窗口中的“我的窗口”。在“检查器”窗口中将标题设置为“Tiff Viewer”。属性的“检查器”窗口应如图 7 所示。
您需要添加一个菜单项,以便您可以打开图像文件。要创建新的菜单项,请从“调色板”窗口中选择“菜单调色板”,将“项目”菜单拖动到“主菜单”(在“隐藏”菜单项上方)并放下。单击“主菜单”中新创建的“项目”菜单选项,从“检查器”窗口将其标题设置为“加载图像”,然后按“返回”。
现在,您需要创建一个控制器类,该类将与用户界面交互。单击“文件”窗口中的“类”图标,然后从树视图中选择“NSObject”项。单击 Gorm 菜单中的“类”菜单项,然后选择“创建子类...”。在“文件”窗口中的“类”树视图中,您现在将找到一个“NewClass”条目。双击“NewClass”项,并将文本替换为“AppController”。
接下来,您需要为您的 NSImageView 对象创建一个出口。出口是引用对象的实例变量——在本例中,是 NSImageView 对象。要向 AppController 类添加出口,请单击 AppController 类右侧的“出口”图标(在“文件”窗口中);单击 Gorm 菜单中的“类”菜单项,然后选择“添加出口/操作...”。在“文件”窗口中的“类”树视图中,您现在将找到一个 newOutlet 条目作为 AppController 的子项。双击 newOutlet 项,并将文本替换为“imageView”。重复这些步骤以添加窗口出口。
创建出口后,您需要向控制器添加一个操作。操作是目标-操作方法。要向控制器添加一个操作,请单击 AppController 类右侧的“操作”图标(在“文件”窗口中);单击 Gorm 菜单中的“类”菜单项,然后选择“添加出口/操作...”。在“文件”窗口中的“类”树视图中,您现在将找到一个 newAction: 条目作为 AppController 的子项。双击 newAction: 项,并将文本替换为“loadImage:”。
现在您可以实例化您的 AppController 类,以便从其类模板生成特定对象。您需要实例化您的控制器类,因为 Gorm 连接的是实时对象。在“文件”窗口的树视图中选择“AppController”项,然后单击“类”菜单中的“实例化”菜单项。
现在您可以将您的实时对象(在本例中为 NSImageView)连接到您的出口并设置操作。要将 NSImageView 对象连接到您的 AppController 实例,请单击“文件”窗口中的“对象”图标,然后按住 Ctrl 键的同时,从“文件”窗口中的“AppController”图标拖动到“Tiff Viewer”窗口中的 NSImageView 对象。单击“检查器”窗口中的“imageView”项,然后单击“连接”按钮。这将 NSImageView 实时对象连接到 imageView 出口。要连接窗口出口,请按住 Ctrl 键的同时,从“文件”窗口中的“AppController”图标拖动到“文件”窗口中的“我的窗口”图标。现在,单击“检查器”窗口中的“窗口”项,最后,单击“连接”按钮。图 8 说明了窗口对象与其出口之间的连接。

图 8. 窗口对象与其出口之间正在建立连接
要设置“加载图像”菜单项的操作,请按住 Control 键并单击菜单项,然后将其拖动到“文件”窗口中的“AppController”实例图标。然后,单击“检查器”窗口中的“目标”,选择“loadImage:”项,然后单击“连接”按钮。这将“加载图像”菜单项的操作设置为“loadImage:”。因此,当“加载图像”菜单项收到用户的单击时,将调用“loadImage:”方法。
现在,通过从“文档”菜单中选择“保存”菜单项来保存所有内容。将其命名为 MainMenu。这将创建一个 MainMenu.gorm 目录,其中包含应用程序的存档视图。
最后,通过在“类”树视图中选择“AppController”类条目,然后从“类”菜单中选择“创建类的文件...”来创建 AppController 类的源文件。保持名称不变,只需单击“确定”按钮。这将创建两个文件:AppController.m 和 AppController.h。
现在,退出 Gorm,打开您喜欢的编辑器并修改 AppController.h,使其看起来像列表 1。完整的带有注释的源代码可用;请参阅资源。
然后,修改 AppController.m(AppController 类的实现),使其看起来像列表 2。
现在,为应用程序创建一个非常基本的模型——ImageModel。这个小类将保存当前显示的图像。现在创建 ImageModel 类的实现,如列表 3 和 4 所示。
现在,创建一个小的属性列表,如列表 5 所示,您可以在其中指定应用程序名称、描述和启动时要加载的主 Gorm 文件的名称。
然后,创建一个小的 GNUmakefile 以编译和链接您的小型应用程序。GNUmakefile 应如列表 6 所示。
最后,编译并启动小型应用程序
# make # openapp TiffViewer.app
应用程序启动后,单击“加载图像”菜单项并选择一个 TIFF 文件。它应该在窗口中正确显示,如图 9 所示。
当将应用程序从 GNUstep 移植到 Mac OS X(或反之亦然)时,必须考虑一些重要事项。例如,当移植到 Mac OS X 时,您必须使用 Mac OS X 下的 Interface Builder 重做用户界面。将应用程序移植到 Mac OS X 需要以下步骤
从 Project Builder 的“文件”菜单中,选择“新建项目...”,然后选择“Cocoa 应用程序”。单击“下一步”按钮。
指定项目名称(Tiff Viewer)和项目位置。单击“完成”按钮。
现在,选择“类”节点,并从“项目”菜单中添加文件 AppController.m 和 ImageModel.m。
展开“其他源文件”节点,并删除 main.m 文件。
展开“资源”节点,双击“MainMenu.nib”节点。这将启动 Interface Builder。
就像您在 Gorm 下所做的那样,将 NSImageView 拖放到空窗口中,并将“加载图像”菜单项拖放到“文件”菜单中。
由于控制器类 (AppController) 是在上一节中创建的,因此您可以简单地在 Mac OS X 下重用它。在 Interface Builder 中,从“类”菜单中选择“读取文件..”,然后选择 AppController.h。
从“文件”窗口中,单击“类”选项卡,选择“AppController”,然后从“类”菜单中选择“实例化 AppController”。
现在,像我们在 Gorm 下所做的那样连接出口和操作。
保存修改后的界面,然后退出 Interface Builder。
从 Project Builder 的“构建”菜单中,选择“构建并运行”。这将编译并启动应用程序。
应用程序启动后,从文件菜单中选择“加载图像”,然后选择要显示的图片。最终结果应如图 10 所示。

图 10. 同一应用程序在 Mac OS X 下运行
如您所见,我们移植了应用程序,而没有重写一行代码。即使应用程序非常简单,也可以在 GNUstep 下开发复杂的应用程序,并轻松移植到 Mac OS X。Affiche 和 GNUMail.app 是在 GNUstep 和 Mac OS X 之间可移植的应用程序的良好示例。
反过来,从 Mac OS X 移植应用程序到 GNUstep 时应更加小心。首先,您必须使用 Gorm 重做应用程序的用户界面。其次,GNUstep 目前不提供某些 Cocoa 类的实现,例如 NSToolbar、NSDrawer 或任何核心基础服务。为了避免在将使用这些未实现功能的 Mac OS X 应用程序移植到 GNUstep 时出现问题,您需要使用条件编译。最后,必须创建一个或多个 GNU Makefile,以便在 GNUstep 下编译应用程序。
正如我们在本文中看到的那样,开发 GNUstep 应用程序相对容易。GNUstep 为使用 Objective-C 语言开发真正的跨平台应用程序提供了丰富、清晰且一致的 API。
新的应用程序套件后端正在为 Microsoft Windows、DirectFB 和 Ghostscript 开发,从而支持更广泛的计算环境。此外,最近通过 NSOpenGLView 类的实现添加了 OpenGL 支持。
最后,基于 GNUstep 的发行版正在涌现。例如,LinuxSTEP 项目旨在创建一个完全集成的桌面 Linux 操作系统环境,该环境不受常见 Linux 发行版的一些更传统方法的约束。
本文中引用的所有列表都可以通过匿名下载在 ftp.linuxjournal.com/pub/lj/listings/issue108/6418.tgz 获取。
电子邮件:ludovic@Sophos.ca
Ludovic Marcotte (ludovic@inverse.ca) 拥有蒙特利尔大学计算机科学学士学位。他目前是 Inverse inc. 的软件架构师,Inverse inc. 是一家位于蒙特利尔市中心的小型 IT 咨询公司。