语言、平台、链接库,这三者之间有很密切的关系。本文尝试着以链接库为中心,探讨它们之间的现况。
语言与链接库
语言通常会伴随着链接库,没有链接库的语言,差不多什么程序都写不出来。比方说,用 C 语言写出一个印出 Hello 的小程序,你需要用到 stdio 的链接库。用 Python 写 GUI 程序,你需要 Tkinter 链接库。
平台与链接库
平台通常也会伴随着链接库,没有链接库的平台,等于是摆明了不希望别人开发此平台的程序。比方说,你想用 Visual C++ 6 开发 Windows 程序,你需要用到 GDI32 以及 USER32 或 MFC 等链接库。写 Mac OS 9 的程序,需要 Carbon 链接库。
平台的链接库 vs 语言的链接库
在 A 平台上用 B 语言开发软件,你会同时面对 A 平台的链接库和 B 语言的链接库,此二链接库因为是不同厂商所提供的,所以可能无法百分之百契合,特别是牵涉到内存管理、资源管理、执行绪等和操作系统有密切关系的主题时。如果你想进行的某功能在 A 平台的链接库和 B 语言的链接库都有提供,那么你应该使用 A 平台链接库的版本,通常比较安全些。比方说,用 C 语言开发 Windows 平台的程序,如果你想配置内存,那么你应该呼叫 Win32 API 的版本(比方说 GlobalAlloc()),而非 C 语言的版本(比方说 malloc())。
跨平台的链接库
你为某平台所开发的程序,为什么不能在别的平台上重新编译之后就能执行?问题就出在平台的链接库上。比方说,你用 C 语言搭配 C 的标准链接库和 Win32 链接库,在 Windows 平台上开发出一个演示文稿软件 WeakPoint 2000;你将 WeakPoint 2000 的原始程序拿到 Linux 上编译,却无法编译成功,问题就出在 Linux 没有 Win32 的链接库。
那么,如果有一个链接库将各个主要平台的链接库萃取(abstract)出一个共通的链接库,不就可以解决这个问题了。例如 Qt 正是这么做,你的 C++ 程序如果只使用标准的 C++ 链接库和 Qt 链接库,你就可以把程序重新编译之后在不同的平台(Linux,Unix,Windows)上执行。
语言 + 平台 + 链接库
Java 就更了不起了,不但将链接库统一起来,更将平台统一起来,也就是说程序不用重新编译,就可以直接执行。但是也因此,多了一层 JVM,牺牲了一部分的效率。
跨语言的链接库
Borland 的 VCL 链接库是在 Windows 平台上相当受好评的一套链接库,可以被 C++ 和 Object Pascal(Delphi)使用。其实「跨语言的链接库」不是一种很好的说法,毕竟许多语言都可以连结外部原生链接库,两者不需要是同一种语言。但是这样的连结是否需要大费周章,则有相当大的差异。而 Delphi 和 C++ Builder 使用 VCL 则是相当方便的。
即将在本月底问世的 Mac OS X,提供了 Cocoa 链接库。Cocoa 链接库可以被 Objective-C 和 Java 语言使用。Objective-C 和 Java 语言版的 Cocoa 链接库相似性在九成以上。Java 在 Mac OS X 的原生程序设计上被简化成一个纯语言,完全不使用 Java 的 API,只使用 Cocoa 链接库,这倒是挺特别的。(当然 Mac OS X 也另外会有 JVM 来支持一般的 J2SE)
语言规格 + 平台 + 链接库 = 包山包海 ?
.NET 比 Java 的眼光更高,甚至准备将语言规格也统一起来。.NET 有一个 CLS(common language specification),任何语言只要符合 CLS 这个标准,就可以轻易地整合进 .NET 平台,享用 .NET 平台的资源。这一点就是 Java 比不上的。虽然别的语言一样可以设计出编译器来将程序编译成 Java bytecode,在 JVM 上执行,但 Java 并没有提供直接的支持,所以要移植一个语言到 Java,比移植一个语言到 .NET 来得困难。
.NET 虽然允许各种语言,但是为了因应 CLS,所以各个语言常常需要做出妥协更改语言本身,比方说 Visual Basic 的更改幅度就很大(Visual Basic 7 差不多是一个新的语言了),而 JScript 和 Visual C++ 的语言也都有改变。这种方式的语言中立性,无疑是削足适履。有了 CLS 的规范,这些语言会趋于一致,思维模式如出一辙,只有一些微不足道的小差异。历史会证明,C# 会是 .NET 平台上独大的语言,.NET 上的其它语言都将沦为点缀,这么一来,跨语言的宣示,竟成了一个幌子。虽然我对 .NET 的语言中立性这点颇有疑异,但我倒是挺喜欢 .NET framework 的,我忍不住竖起大拇指称赞 .NET framework 是「歹竹出好笋」。
.NET 的语言规格和链接库都是统一的。命运多舛的 Eiffel 将 .NET 视为救命的浮木,准备将 Eiffel 移植到 .NET,但这么一来,Eiffel 势必得放弃自行开发的 Windows 专用链接库 WEL(Windows Eiffel Library)与跨平台的链接库(比方说 EiffelVision 等)。难道 Eiffel 没有发现它所以为的浮木,其实是鳄鱼伪装的?
同样的问题也会发生在 Delphi 上,如果 Delphi 准备移植到 .NET,也必须更改一部分的语言特性,并可能要放弃在 .NET 上使用 VCL(CLX)。Delphi 这么做一点好处都没有。
最乱的时代,最好的选择
看完这篇文章,你可能已经头昏脑胀了。没关系,你只要记得下面这句话就好了:最乱的时代,最好的选择 ...Java。