第十一章 JNI设计概述 本章给出了JNI设计的概述,必要时,我们也提供底层技术的动机。设计概述作为关键JNI概念(如JNIEnv接口指针,本地和全局引用以及字段和方法ID)的规范。技术动机旨在帮助读者了解各种设计的权衡。有几次,我们将讨论如何实现某些功能。这种讨论的目的不是提出一个实际的实施策略,而是要澄清微妙的语义问题。 桥接不同语言的编程接口的概念并不新鲜。例如,C程序通常可以调用用FORTRAN和汇编语言编写的函数。同样,编程语言(如LISP和Smalltalk)的实现也支持各种外部…
第十一章 JNI设计概述 本章给出了JNI设计的概述,必要时,我们也提供底层技术的动机。设计概述作为关键JNI概念(如JNIEnv接口指针,本地和全局引用以及字段和方法ID)的规范。技术动机旨在帮助读者了解各种设计的权衡。有几次,我们将讨论如何实现某些功能。这种讨论的目的不是提出一个实际的实施策略,而是要澄清微妙的语义问题。 桥接不同语言的编程接口的概念并不新鲜。例如,C程序通常可以调用用FORTRAN和汇编语言编写的函数。同样,编程语言(如LISP和Smalltalk)的实现也支持各种外部…
第十章 陷阱与缺陷 为了突显前面几章中介绍的重要技术,本章涵盖了JNI程序员长犯的一些错误。这里描述的每个错误都发生在现实世界的项目中。 10.1 错误检查 编写本地方法最常见的错误是忘记检查是否发生了错误情况。与Java编程语言不同,本地语言不提供标准的异常机制。JNI不依赖于任何特定的本地异常机制(例如C++异常)。因此,在执行每一个可能会引起异常的调用后,程序员都需要执行显式检查。并不是所有的JNI函数都会引起异常,但是大多数都可以检查。异常检测是单调的,但是为了确保使用本地方法的应用程序的健壮性,确实有必须…
第九章 利用现有的本地库 JNI的一个应用就是利用已存在的本地库中现有的代码来编写本地方法。本章介绍的一个典型方法是生成一个封装了一系列本地方法的类库。 本章首先介绍编写包装类最直接的方法--一对一映射。然后我们介绍一项技术,共享桩,来简化编写封装类的任务。 一对一映射和共享桩都是封装本地方法的技术。在本章的最后,我们还将讨论如何使用peer类来封装本地数据结构。 本章中描述的方法直接使用本地方法公开本地库,因此具有使得调用这种本地方法的应用程…
第八章 附加的JNI特性 我们已经讨论过用于编写本地代码的和在本地程序中嵌入一个Java虚拟机实现的JNI特性。这一章我们将介绍剩余的JNI特性。 8.1 JNI和线程 Java虚拟机支持在同一地址空间中同时执行的多个控制线程。这种并发性引入了一定程度的复杂性,这个在单线程环境中是没有的。多线程可以同时访问同一个对象,同一个文件描述符(简称相同的共享资源)。 为了充分利用本节,你应该熟悉多线程编程的概念。你应该知道如何编写使用多线程以及如何同步访问共享资源的Java应用程序。关于Java编程…
第七章之刻意练习 练习1: 学会在C代码中创建虚拟机,复习类、方法ID的查找 在native侧,使用random函数生成一个包含1000个整型的数组,然后在native侧调用Java编程语言中的Arrays.sort(int [])方法对数组进行排序,然后打印数组的前100个数。 ** 下面是博主自己写的答案 ** 首先直接给上代码 [crayon-62bccba490e09303631757/] 上面的代码主要是学会在C程序中创建JavaVM以及调用Java编程语言中的方法。自己写过一两次应该也就会了。然后就是编…
第七章:调用接口 这一章用于说明在你的本地代码中如何嵌入一个Java虚拟机。Java虚拟机实现通过作为一个本地库来传输,本地应用程序可以连接此库并使用调用接口来加载Java虚拟机。的确,在JDK或Java 2 SDK版本中的标准启动器指令只不过是一个和Java虚拟机链接的简单c程序。启动器解析命令行参数、加载虚拟机、并通过调用借口运行Java程序。 7.1 创建Java虚拟机 为了说明调用借口,让我们先看一个加载一个Java虚拟机并调用按照如下定义的Prog.main方法的C程序 [crayon-62bccba49…
第六章之刻意练习 经过第六章的学习,基本了解JNI的异常处理了,现在我们来刻意练习一下 practice 1, 在native层获取Java异常并将异常抛出给Java层 我们需要在native方法中实现除法,除法的除数是不能为零的,所以如果Java在调用native方法的除法时,穿进去的第二个参数为0的话,我们就要抛出一个 java.lang.ArithmeticExpection:/by zero的异常到Java空间中,然后再Java空间中处理这个异常。Java侧的工作就比较简单了,我们只…
第六章 异常 我们已经遇到大量在本地代码中需要检查执行JNI方法后可能产生的错误。这一章将介绍本地代码如何从这些错误状况中检测和修复。 我们将会重点关注作为JNI函数调用的结果发生的错误,而不是在本地代码中发生的任意错误。如果一个本地方法进行了操作系统调用,则只需要按照文档说明的方式来检查系统调用中可能发生的错误。另一方面,如果本地方法想Java API方法进行回调,则必须按照本章中描述的步骤来正确的检查和修复方法执行期间可能产生的异常。 6.1 概述 我们通过一些列…
第五章 本地和全局引用 JNI将实例和数组类型(例如jobject、jclass、jstring和jarray)公开为不透明引用。本地代码不能直接检查不透明引用指针的内容。而是通过JNI函数来获取不透明引用所指向的数据结构。通过处理不透明引用,你不必担心依赖于特定Java虚拟机的内部对象数据结构布局。但是,在JNI中,你需要了解更多有关于不同类型的引用: JNI支持三中透明引用:本地引用,全局引用和弱全局引用 本地和全局引用拥有不同的生命周期。本地引用会被自动回收,而全局引用和弱全局引用会一…
第四章之刻意练习 Practice 1 在Java侧定义两个成员变量,一个为静态成员变量,另一个为非静态成员变量。在Java侧初始化并打印这两个值,然后再native侧修改这两个值,返回到Java侧后再打印这两个值。定义这两个值一个为String类型,另一个为double类型好了。 ** 下面是博主写的答案 ** Java侧代码: [crayon-62bccba492f61429668927/] native侧代码: [crayon-62bccba492f70713732765/] Practice 2 在Java…