开发工具:
文件大小: 1mb
下载次数: 0
上传时间: 2019-10-12
详细说明:java jni 中文官方规范,从数据结构和接口类型介绍,各种数据类型的转换和使用;动态加载库的方式;简单易上手;Java application
Jaya yirtual machine
Native application
and library
Imp lementation
and library
Host environment
图11N的角色
JN|可以这样与木地程序进行交互:
1、你可以使用小N来实现“本地方法”( native methods),并在JAVA程序中
调用它们。
2、JNI支持一个“调用接口”( invocation interface),它允许你把一个』WM嵌
入到本地程序中。本地程序可以链接一个实现了」wM的本地库,然后使用“调
用接口”执行JAVA语言编写的软件模块。例如,一个用C语言写的浏览器可以
在一个嵌入式M上面执行从网上下载下来的 applets
1.3JN|的副作用
请记住,一旦使用N,JAVA程序就丧失了JAVA平台的两个优点:
1、程序不再跨平台。要想跨平台,必须在不同的系统环境下重新编译本地语言
部分。
2、程序不再是绝对安全的,本地代码的不当使用可能导致整个程序崩溃。
一个通用规则是,你应该让本地方法集中在少数几个类当中。这样就降低了JAV
A和C之间的耦合性。
1.4什么场合下应该使用JN
当你开始着手准备一个使用JN的项目时,请确认是否还有替代方案。像上一节
所提到的,应用程序使用N会带来一些副作用。下面给出几个方案,可以避免
使用JN的时候,达到与本地代码进行交互的效果
1、JAVA程序和本地程序使用 TCP/IP或者PC进行交互。
2、当用」AVA程序连接本地数据库时,使用JDBC提供的AP|。
3、JAVA程序可以使用分布式对象技术,如 JAVA IDL AP。
这些方案的共同点是,JAVA和C处于不同的线程,或者不同的机器上。这样,
本地程序崩溃时,不会影响到」AVA程序
下面这些场合中,同一进程内N的使用无法避免:
1、程序当中用到了 JAVA APⅠ不提供的特殊系统环境才会有的特征。而跨进程
操作又不现实。
2、你可能想访问一些己有的本地库,但又不想付出跨进程调用时的代价,如效
率,内存,数据传递方面。
3、JAVA程序当中的一部分代码对效率要求非常髙,如算法计算,图形渲染等
总之,只有当你必须在同一进程中调用本地代码时,再使用」N。
1.5JN的演化
JDK1.0包含了一个本地方法接口,它允许JAVA程序调用CC++写的程序。许多
第三方的程序和JAVA类库,如: java. lang java. io, java. net等都依赖于本地方法来
访问底层系统环境的特征。
不幸的是,JDK10中的本地方法有两个主要问题
1、本地方法像访问C中的结构( structures)一样访问对象中的字段。尽管如此,
丿VM规范并没有定义对象怎么样在内存中实现。如果一个给定的JM实现在布
局对象时,和本地方法假设的不一样,那你就不得不重新编写本地方法库。
2、因为本地方法可以保持对mM中对象的直接指针,所以,JDK10中的本地方
法采用了一种保守的GC策略。
JN的诞生就是为了解决这两个问题,它可以被所有平台下的VM支持:
每一个ⅦM实现方案可以支持大量的本地代码。
2、开发工具作者不必处理不同的本地方法接口
3、最重要的是,本地代码可以运行在不同的MM上面。
JDK1.1中第一次支持JN,但是,JDK1.1仍在使川老风格的本地代码来实现JAV
A的AP。这种情况在」DK1.2下被彻底改变成符合标准的写法
1.6例了程序
本书包含了大量的代码示例,还教我们如何使用 java来构建JN程序。
2从一个简单的例子开始
木章通过一个简单的例子来示例如何使用JNI。我们写一个JAVA程序,并用它
调用一个C函数来打印“He11oWor1d!”。
2.1概述
图2.1演示了如何使用JAVA程序调用C函数来打印“ Hello World!”。这个过
程包含下面儿步
创建个类( Helloworld.java)声明本地方法
2、使用 Javac编译源文件 HollowWorld.java,产生 HelloWorld. class。使用
javan-jini来生成C头文件( Helloworld.h),这个头文件里面包含了本地
方法的函数原型。
3、用C代码写函数原型的实现。
4、把C函数实现编译成一个本地库,创建He1lo- World.dl1或者 libHello-W
orld.so。
5、使用java命令运行 elloWorld程序,类文件le1 LoWorld.c1ass和木地库
( HelloWorld.d11或者 libHelloworld.so)在运行时被加载。
Create a class
that declares the
natie method
He11。yld.java
U se javac
Use java to
to compile the
enerate header
program
file
Hello World. h
Hellotor ld. class
Write the c
implementation
of the natⅳe
入 method
Ha11。wr1dc
code and generate
lil
Run the
program tising
Interpreter
Hello world
图2.1编写并运行“ Helloworld”程序
本章剩余部分会详细解释这几步
3基本类型、字符串、数组
开发者使用JNI时最常问到的是JAVA和C/C++之间如何传递数据,以及数据类
型之间如何互相映射。本章我们从整数等基本类型和数组、字符串等普通的对象
类型开始讲述。至于如何传递任意对象,我们将在下一章中进行讲述。
个简单的本地方法
JAVA端源代码如下
class Prompt
/ native method that prints a prompt and read
ne
private native String getLine (string prompt
public static void main (String args[])t
Prompt p= new Prompt)
String input= p. gelline( Type a line:")
ystem out println( User typed
t inpu
static
System loadLibrary( prompt")
3.1.1本地方法的C函数原型
Prompt. getline方法可以用下面这个C数来实现:
JNIEXPORT jstring JNICALL
Java Prompt getLine(jnienv env, jobject this, jstring promp
其中,JⅥ IEXPORT和 UNICALL这两个宏(被定义在jni.h)确保这个函数在本地
库外可见,并且C编译器会进行正确的调用转换。C函数的名字构成有些讲究,
在11.3中会有一个详细的解释
3.1.2本地方法参数
第一个参数 NIEN接口指针,指向一个个函数表,函数表中的每一个入口指向
个JNⅠ函数。本地方法绎常通过这些函数来访问JⅧM中的数据结构。图3.1
演示了JⅥIEnv这个指针
JI工E卫建
foin
to ini functions
an interface
Pointer
Pointer
unct卫
Ltc-aawi如l
pointe
an interface
Pointe
structures)
function
an inteiface
function
图3.1 JNIEnv接口指针
第二个参数根据木地方法是一个静态方法还是实例方法而有所不同。木地方法是
个静态方法时,第二个参数代表本地方法所在的类;本地方法是一个实例方法
时,第二个参数代表本地方法所在的对象。我们的例子当中, Java Prompt get
Line是个实例方法,因此 jobject参数指向方法所在的对象。
3.1.3类型映射
木地方法声明中的参数类型在木地语言中都有对应的类型。JNI定义了一个C/C
++类型的集合,集合中每一个类型对应于JAVA中的每一个类型。
JAVA中有两种类型:基本数据类型(int, float,char等)和引用类型(类,对
象,数组等)
JNI对基本类型和引用类型的处理是不同的。基本类型的映射是一对一的。例如
JAVA中的int类型直接对应CC++中的jint(定义在jni.h中的一个有符号3
2位整数)。12.1.1包含了JNI中所有基本类型的定义
INI把JAVA中的对象当作一个C指针传递到本地方法中,这个指针指向JWM中
的内部数据结构,而内部数据结构在内存中的存储方式是不可见的。本地代码必
须通过在八NIEnⅴ中选择适当的JNⅠ函数来操作J硎M中的对象。例如,对于java.
lang. String对应的JNI类型是 Jstring,但本地代码只能通过 GetStringUTFCh
ars这样的JNI函数来访问字符串的内容。
所有的JⅥI引用都是 job ject类型,对了使用方便和类型安全,NI定义了一个
引用类型集合,集合当中的所有类型都是 jobject的子类型。这些子类型和JAV
A中常用的引用类型相对应。例如, jstring表示字符串, job jectarray表示对
象数组
3.2访问字符串
Java prompt getline接收一个 jstring类型的参数 prompt, Jstring类型指向
JWM内部的一个字符串,和常规的C字符串类型char*不同。你不能把 jstring
当作一个普通的C字符串
3.2.1转换为本地字符串
本地代码中,必须使用合适的JNI函数把 Jstring转化为C/C++字符串。JNI支
持字符串在 Unicode和UTF-8两种编码之间转换。 Unicode宇符串代表了16-bi
t的字符集合UTF-8字符串使用一种向上兼容7- bit Ascii字符串的编码协议。
UTF-8字符串很像NULL结尾的C字符串,在包含非 ASCII字符的时候依然如此。
所有的7- bitASCII字符的值都在1~127之间,这些值在UF-8编码中保持原样。
个字节如果最高位被设置了,意味着这是一个多字节字符(16- bitUnicode值)。
函数 Java prompt getline通过调用JNI函数 GetstringUTFChars来读取字符串
的内容。 GetstringutFchars可以把一个 Jstring指针(指向JW内部的 Unico
de字符序列)转化成一个UTF-8格式的C字符串。如何你确信原始字符串数据
只包含7- bit AsCIi字符,你可以把转化后的宇符牛传递给常规的C库函数使
用,如 printf。我们会在8.2中讨论如何处理非 ASCII字符串。
JNIEXPORT jstring JNICALL
Java Prompt getLine(jnienv env, jobject obj, jstring prompt)
(系统自动生成,下载前可以参看下载内容)
下载文件列表
相关说明
- 本站资源为会员上传分享交流与学习,如有侵犯您的权益,请联系我们删除.
- 本站是交换下载平台,提供交流渠道,下载内容来自于网络,除下载问题外,其它问题请自行百度。
- 本站已设置防盗链,请勿用迅雷、QQ旋风等多线程下载软件下载资源,下载后用WinRAR最新版进行解压.
- 如果您发现内容无法下载,请稍后再次尝试;或者到消费记录里找到下载记录反馈给我们.
- 下载后发现下载的内容跟说明不相乎,请到消费记录里找到下载记录反馈给我们,经确认后退回积分.
- 如下载前有疑问,可以通过点击"提供者"的名字,查看对方的联系方式,联系对方咨询.