Sun-JNI文档系列之二——第一章:介绍

     JNI是Java平台的强大特性(powerful)。使用JNI的应用可以将用C或C++编写的本地代码(native code)与Java编写的代码混合到一块。JNI允许开发者利用Java平台的优势而不用舍弃他们投入到旧代码中的精力。因为JNI是Java平台的一部分,开发者一旦解决了互操作性问题,他们就可以要求他们的解决方案在所有Java平台实现上工作(programmers can address interoperability issues once,and expect their solution to work with all implementations of the Java platform.)
     本书既是一本JNI编程指南也是JNI的参考手册。这本书包含下面三个部分:
     1、第二章通过一个简单地例子介绍JNI。这是一个为不熟悉JNI的初学者提供的教程。
     2、第三章到第十章是关于大量的JNI特性的概述,这些概述组成了程序员指南。我们将会学习一些简短的描述性(short but descriptive)例子来重点讲述各种各样的JNI特性,此外,我们还会学习到一些编程技巧,这些技巧早已被证明在JNI编程中用处很大。
     3、第十一章到第十三章展示了所有JNI类型和函数的权威规范。这些章节也被组织作为参考手册使用
     本书适用于对JNI有着不同需求的读者群。(This book tries to appeal to wide audience with different needs for the JNI.)本书的教程和编程指南部分是为初学者准备的,反之,有经验的开发者或者JNI实现者可能会发现参考手册部分更有用。大多数读者可能会是使用JNI的开发者。书中的称呼“你”指的是使用JNI编写程序的开发者,而不是JNI实现者或使用JNI开发的程序的终端用户。
     本书假定你已经具有基础的Java、C、C++知识。如果你不具备这些知识,你可以参考下列优秀图书中的一部分:The Java™Programming Language, Second Edition,by Ken Arnold and James Gosling (Addison-Wesley, 1998),The C Programming Language, Second Edition, by Brian Kernighan and Dennis Ritchie (Prentice Hall,1988), andThe C++ Programming Language, Third Edition, by Bjarne Stroustrup (Addison-Wesley, 1997).
     本章剩下的部分将介绍JNI的背景、扮演的角色和发展过程。
    
     1.1 Java平台与主机环境(host environment)
     因为本书涉及Java以及本地语言(C/C++)编写的应用,因此首先让我们明确下这些语言的开发环境。
     Java平台值得是包含Java虚拟机和Java API的开发环境。Java应用使用Java语言编写,然后编译成机器无关的二进制Class文件。Class文件可以再任何Java虚拟机上执行。Java API包含一系列预定义的Class。任何Java平台的实现都必须保证支持Java编程语言、虚拟机和API。
     主机环境(host environment)这个称呼代表一个主机操作系统、一组本地库和CPU指令系统(instruction set)。本地应用(Native Application)使用本地编程语言(native programming language)比如C和C++编写,然后被编译成特定主机的二进制代码,并且需要依赖本地库。本地应用程序和本地库一般依赖于特定的主机环境。例如,为一个操作系统编译一个C程序,通常不能再其他操作系统上运行。
     Java平台通常部署在主机环境的上层。例如,Java运行时环境(JRE)是Sun的产品,它可以在目前的操作系统比如Solaris和Windows上支持Java平台。Java凭条提供了一组特性使得应用可以独立于平台之下的主机环境。(The Java platform offers a set of features that applications can rely on independent of the underlying host environment.)
     1.2 JNI扮演的角色
     当Java凭条被部署在主机环境的上层,它应当或者必须允许Java应用程序能够与其他语言编写的本地代码紧密合作。程序员开始采用Java平台构建一些传统上用C或C++编写的应用。然而,由于已经存在的在旧代码中的投入,Java应用将会在很长一段时间内与C和C++代码共存。JNI是一个有力的(powerful)特性,它不仅允许你利用Java平台的优势,而且仍然可以使用其他语言编写的代码。作为Java虚拟机实现的一部分,JNI是一个双向接口,允许Java应用调用本地代码,反之亦然(and vice versa)。图1.1阐明了JNI扮演的角色
    
图1.1 JNI扮演的角色
     JNI被设计用来处理这样的情景:当你需要将Java代码和本地代码结合到一起的时候。作为双向接口,JNI支持两种类型的本地代码:本地库和本地应用。
     1、你可以使用JNI写本地方法并允许Java应用调用本地库中实现的函数。Java应用调用本地方法与调用Java方法是相同的。然而,在这个场景背后,本地方法用另一种语言实现并且存在于本地库中。
     2、JNI支持调用接口(invocation interface),允许在本地应用中嵌入Java虚拟机。本地应用可以链接一个实现了Java虚拟机的库,然后使用调用接口执行Java编写的软件组件。例如,一个C编写的web浏览器可以在内嵌的Java虚拟机中执行下载的applet。
     1.3 使用JNI的implication
     请记住,一旦在应用中使用了JNI,他将有失去Java平台的两个优势的风险。     第一,依赖于JNI的Java应用不能直接运行于多种主机环境中。即使应用中Java编写的部分可以再多种主机环境中移植,本地代码编写的部分也必须重新编译。     第二,虽然Java是类型安全并且可靠的,但是本地语言比如C或C++却并非如此。因此,当你使用JNI开发应用程序时,你必须格外小心。一个不规范的(misbehaving)本地方法可以使整个程序受害(corrupt)。基于这种原因,Java应用在使用JNI特性前执行安全检查。
     作为一种通用的规则,你应当规划好整个应用,使本地方法定义在尽可能少的Class文件中。这使得本地代码和应用其余部分的明确的隔离变得必须。(This entails a cleaner isolation between native code and the rest of the application.)
     1.4什么时候使用JNI
     在你着手进行一个使用JNI的项目时,退一步想想那是否是值得的,是否有其他可以选择的更合适的方法。正如上一节提到过的,与严格使用Java开发的应用相比,使用JNI的应用有其固有的缺点。比如,你失去了Java的类型安全保证。
     大量可选的其他方法也允许Java应用与其他语言开发的代码协作,例如:
     1、一个Java应用可以通过TCP/IP连接或其他IPC(inter-process communication)机制与本地应用进行通信
     2、Java应用可以通过JDBC连接旧版数据库(legacy database)
     3、Java应用可以利用分布式对象技术(distributed object technologies)比如Java IDL API的优势
     这些可选的解决方案的共同特性是Java应用与本地代码属于不同的进程(有时候在不同的机器上 )。进程的分离提供了重要的便宜。(Process separation offers an important benefit.)(The address space protection supported by processes enables a high degree of fault isolation—a crashed native application does not immediately terminate the Java application with which it communicates over TCP/IP.)
     然而,有时候你会发现对于一个Java应用来说,与同属于一个进程的本地代码进行通信是必须的。这时候JNI就变得有用了。比如,我们可以考虑如下场景:
     1、Java API不支持特定的依赖于主机的特性,而这些特性正是应用所需要的。例如,应用可能想执行某些操作,特别是不被Java API所支持的文件操作时,如果通过其他进程处理文件,那么就会既麻烦又低效。
     2、你可能想访问已经存在的本地库,而且不想在通过不同的进程复制和传递数据的头部信息上浪费时间。(You may want to access an existing native library and are not willing to pay for the overhead of copying and transmitting data across different processes.)在同一个进程中导入本地库更为高效。
     3、一个拥有多个进程的应用可能会导致不可接受的内存需求。如果这些进程需要运行于同一台客户机上,这通常是真实的。把一个本地库加载到已存在的进程中通常比新建一个进程然后加在本地库到这个进程中需要更少的资源。
     4、你可能想用更低级的语言实现一小段对时间要求苛刻(time-critical)的代码,比如汇编语言。如果一个应用需要较多地处理3D图像并且花费大量的时间进行图像渲染,为了增强应用表现(achieve maximum performance),用汇编写一个图形库的核心部分是必须的。
     总之,如果你的Java应用需要与本地代码在同一个进程中协作时,请使用JNI。
     1.5 JNI的发展
     在Java平台出现初期,Java应用与本地代码的协作需求就得到了广泛的认可。在Java平台第一个发行版本(JDK 发行版1.0)中,就包含了本地方法接口,允许Java应用调用其他语言如C/C++写的函数。与Java类库(例如,Java.lang、java.io、java.net)的实现相同,许多第三方应用依赖于本地方法接口去访问位于平台底层的主机环境特性。
     不幸的是,JDK 发行版1.0中的本地方法接口有两个主要的问题:
     1、第一,本地方法将对象(object)的字段(field)作为C结构体的成员来访问。然而,Java虚拟机规范并没有明确规定对象在内存中怎么设计(how object are laid out in memory)。如果一个给定的Java虚拟机对于对象在内存中的设计并不像本地代码接口设想的那样,那么你必须重新编译本地方法库。
     2、第二,JDK 发行版1.0中的本地方法接口依赖于过时的垃圾回收机制,因为本地方法可以保存直接指向虚拟机中对象的指针。任何使用了更高级的垃圾回收机制的Java虚拟机都不支持JDK 发行版1.0中的本地方法接口。
     JNI被设计用来解决这些问题。JNI是一种可以被运行于各种各样的主机环境上的Java虚拟机支持的接口。使用JNI:
     1、每一个虚拟机可以支持大段的本地代码
     2、开发工具销售者不必处理不同的本地方法接口
     3、更重要的是,应用开发者只需要写一个本地代码的版本,然后这个版本就可以在不同的Java虚拟机上运行。
     JDK发行版1.1中第一次支持JNI。然而,在内部实现上,JDK发行版1.1仍然使用老式的本地方法(和JDK发行版1.0中一样)来实现Java API。在Java 2 SDK发行版1.2(广为人知的JDK发行版1.2)中,这种情况就不存在了。本地方法被重写以确定(confirm)JNI标准。
     JNI是所有Java虚拟机支持的本地接口。从JDK发行版1.1开始,你就应当用JNI编程(而不是本地方法接口)。在Java 2 SDK发行版1.2中,老式的本地方法接口依然支持,但是在将来不会也不可能被更高级的Java虚拟机支持。
     Java 2 SDK发行版1.2包含了大量JNI增强特性(enhancement)。这些增强特性是向后兼容的。JNI将来的发展将会维持完全的二进制兼容性。
     1.6 程序实例
     本书用了大量的示例来讲解(demonstrate)JNI特性。示例程序通常包含多样的代码段,包括Java代码以及C/C++本地代码段。有时候本地代码用到Solaris和Win32独有的特性。我们也将介绍如何使用JDK和Java 2 SDK发行版中附带的命令行工具来构建一个JNI应用。
     请记住,JNI的食欲不受主机环境或特定开发工具的限制。本书重点关注编写代码,而不是构建和运行代码的工具。JDK和Java 2 SDK发行版套件中的命令行工具相当原始。第三方工具可能提供了改进过的方法来构建JNI应用。我们鼓励你自己查阅你选择开发工具套件中的JNI相关文档。
     你可以在下面的网址下载到本书的示例代码以及后续的更新:http://java.sun.com/docs/books/jni/
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值