Windows及Mac OS X在操作系统架构、开发环境、API、图形环境等环节上的相近处与不同的地方,也简单提出了跨平台应用程序开发的两种策略。事实上在两种平台上开发所需要了解的概念跟技能没有太大的不同,两种平台在性能上的差异也不大。大体说来,Windows和Mac OS X都是为桌面应用环境、图形用户接口(GUI)而设计的操作系统。虽然不同平台细节各有特色,但两者相近的抽象概念,其实远远多于相左之处。本文试图指出方向上明显的异同所在,而非详细列举各种细项差别。最后,我也将简短分享自己在开发跨平台软件时的一些技巧和心得。
系统架构与开发环境的差异
用最简单的话来说,Mac OS X与Windows在架构与开发环境上最大的不同点在于:OS X是UNIX也不是UNIX;OS X主要开发工具Xcode使用GCC作为编译程序,与其他种类的UNIX相同;不过OS X也有独树一格的"bundle"软件包装格式这样的东西,成为它与其他操作系统不同之处。
Windows和OS X都属于现代的操作系统,所以Windows在操作系统层级所提供的功能──执行文件与链接库加载、多任务与多线程、内存管理──在OS X上都找得到对等的API和作法。不过,相较于Windows在微软独力开发下,架构和API都维持着相对的一贯性(另一方面,也背负着各种历史遗迹和向下相容的包袱),Mac OS X则是底层源自NeXTSTEP的Mach微核心(现在称为XNU),而应用层(用准确的UNIX术语来说叫userland)来自FreeBSD 4。这件事情相当重要:OS X透过这样的架构,才拥有和一般Linux/FreeBSD相似的UNIX应用环境。有相当多Mac软件开发者喜欢在UNIX shell下工作,使用各种UNIX工具。在Windows上,必须加装Cygwin之类的环境才能办到。
Apple几年前有则广告是「把其他牌子的UNIX送进/dev/null里」(用过UNIX的朋友应该不难体会其中的吹嘘意涵)。平心而论,OS X受益自UNIX环境之处不少。尤其,Apple使用了大量的open source工具。举例来说,Apple不像微软,没有自己的C语言编译工具,Apple用的是UNIX业界的标准──open source的GCC(其中当然有不少OS X的扩展功能就是)。虽然Apple有自己的开发环境Xcode,但是底层采用GCC这件事对开发者来说是相当重要的。同时,Apple的C/C++链接库用的也是GCC标准的stdc/stdc++。了解这个差异,在遇到与Microsoft C/C++ compiler不同的地方时,就更容易能找到解答的资源(这类型问题往往不限于OS X,其他UNIX平台也会发现)。
但是Mac OS X并不完全是UNIX。它的GUI环境(Aqua)就完全不是一般Linux/FreeBSD所使用的X11。而在UNIX层之下的微核心也和其他UNIX不同。接下来这一点很重要:OS X虽然有和Windows .EXE和.DLL相对应的文件(OS X跟其他UNIX一样,可执行文件一般不加扩展名,UNIX系的动态加载链接库则冠以.dylib),但更重要的架构差异是bundle。
Bundle概念承袭自NeXTSTEP。简单来说,就是由操作系统提供一种类似对象封装的文件包裹。OS X上最常见的bundle要属.app结尾的应用程序了。虽然.app外观上是个文件,在UNIX shell下看就能发现它其实是个目录,内含各种metadata(通常至少会有一个名为Info.plist的数据文件)、可执行文件、动态链接模块、各种资源等。除了.app外,OS X的各种框架档(以.framework结尾,是一种同时包含头文件及链接库的包装)、应用程序的外挂模块(通常以.bundle结尾)等等,都是以bundle形式呈现的。了解这个差异,才能了解为什么OS X上很少有程序需要额外的安装程序,也鲜少听说有所谓的"DLL hell"(因共享链接库版本不兼容造成的困扰)。
项目 Windows Mac OS X
操作系统最近桌面版本 Windows Vista Mac OS X 10.5 Leopard
操作系统核心 NT Kernel XNU
CLI Shell环境 CMD.EXE UNIX shell (bash/tcsh/etc., 可使用Terminal.app一类的终端机软件进入)
GUI (Shell) 环境 Windows Explorer Aqua (Finder)
程序二进制文件格式 Portable Executable (PE): .EXE, .DLL Mach-O "universal" binary (可执行文件通常不带附加名,DLL结尾为.dylib)
用来辨认软件组件的方式 GUID bundle identifier (Java式的id,例如com.apple.TextEdit)
厂商提供或贩卖的开发环境 Microsoft Visual Studio Xcode
可视化的GUI制作工具 Visual Studio内建的WinForm designer Interface Builder
C编译程序 Microsoft C Compiler GCC
表一:Windows与Mac OS X在架构上的对照
开发语言与API;Objecitve-C, Core API, Carbon, Cocoa
如果使用微软工具来开发Windows软件,就一定会碰到Platform SDK,MFC或者.Net平台,同时,也相对应到C、C++、C#和其他.Net平台所提供的语言(这种区分并不是绝对的,仅仅是为了方便接下来的模拟所做的简化)。在OS X上,Apple则是鼓励大家尽量采用Objective-C作为开发语言,并且熟悉Cocoa。
接下来的问题既尴尬又麻烦。很多人会问:我们是否非学Objective-C不可?另外一个常见的问题是:Apple不是也有名叫Carbon的C API吗?(延伸出来的问题则是:可不可以用C++开发Mac程序?)。
简单的答案(同时一定程度上也代表Apple的态度)是:要用Objective-C才能完全发挥OS X图形应用环境的长处,而Cocoa这个用Objective-C写成的API framework就是最佳的施力点。#p#分页标题#e#
复杂的答案则是这样:
OS X的本体,也就是所有非UNIX的部份,并不像Windows一开始就(几乎)全以C写成的。因此OS X没有所谓"Win32 API"这么纯粹的东西。OS X核心的、非GUI的服务和链接库,有时称为"Core API"。Core API大部分以C写成,并且多半奠基于CoreFoundation这套链接库之上。CoreFoundation提供了一贯的内存管理模式(CFRetain, CFRelease)、基础的数据型别(字符串、数组、字典)、property list文件管理、文件、网络存取等等。CoreFoundation使用上跟Win32 API有点相似,都透过存取handle的方式来达到某种近似「用C语言操作对象」的效果。但CoreFoundation最大的不同在于它还有reference counting的内存管理模式,大幅简化了内存管理的复杂性。
至于Carbon,严格说来,是Mac OS X在发行之初,为了维持与Mac OS 9兼容,才提供一套以C写成的GUI工具集,主要包括所有的GUI组件(Apple 称为 HIToolbox ,HI 意思是 Human Interface)以及所有OS X之前的API(QuickDraw等等)。随着OS X 10.5的推出,Apple渐渐舍弃了旧式的API ,鼓励大家使用Objective-C写成的Cocoa来开发程序。Carbon现在的意义等于就是HIToolbox,也就是OS X GUI 的C API。
但是,Apple在2007年夏天做了重大的宣布;Carbon不会有64-bit的版本。也就是说这一套C API是「没有未来」的。这意味着所有使用Carbon写成的软件──Microsoft Office、Adobe Photoshop都不可能顺利过渡到64-bit。至于像QT这一类跨平台的GUI kit也势必要顺应这项改变。
其实Objective-C并不难学。由C转换到C++/C#时需要学习很多新观念、新用语,但Objective-C大体上只是在C语言上加上一层薄薄的、动态的面向对象层。Cocoa则是相当容易上手的API。透过Cocoa就可以用面向对象的方式存取OS X八成上的系统服务(其余两成可以用C来呼叫)。Objective-C可以跟C完全混用。同时Apple也提供了所谓的"Objective-C++",可以在C++程序中呼叫Objective-C程序,或者在Objective-C里撰写C++程序代码。Apple自家的浏览器Safari就有不少核心的程序代码(WebKit)使用了Objective-C++来撰写。
项目 Windows Mac OS X
主要开发语言 C/C++/C#(及其他.Net支持的语言,如C++/CLI) Objective-C/Objective-C++/C/C++
操作系统服务 Win32 API 系统服务多半可从POSIX layer用stdc/stdc++取用
系统核心服务 Win32 API CoreFoundation/CoreServices
绘图与GUI Win32 (GDI32, USER32) Quartz (C API)/HIToolBox (Carbon)/AppKit (Cocoa)
面向对象的API .NET Framework/MFC Cocoa
面向对象的GUI及绘图系统 WPF/GDI (with MFC) AppKit (Cocoa)以及Cocoa Graphics
桌面应用程序的数据库方案 ODBC/ADO.Net CoreData
基础绘图系统使用的单位 Pixel (GDI) Point (Quartz)
默认的屏幕分辨率 96 DPI 72 DPI
标签: