Board logo

标题: Java本地接口工作方式初探 [打印本页]

作者: qingqing3721    时间: 2011-7-22 23:32     标题: Java本地接口工作方式初探

Java本地接口(Java Native Interface (JNI))允许运行在Java虚拟机(Java Virtual
Machine (JVM))上的代码调用本地顺序和类库, 或者被它们调用, 这些顺序和类库可以是其它语言编写的, 比如C、C++或者汇编语言。
  当一个顺序无法完全运用Java编写时, 开发者可以通过JNI来编写本地方法, 比如标准Java类库并不支持的依赖于平台的特征或者顺序库。
JNI还可以用于修改现有的运用其它语言编写的顺序, 使它们可以通过Java编写的顺序来访问。
  很多基本类库都依赖JNI来为开发者和用户提供效劳, 比如文件的输入/输入和音频功用。 在基本类库中包含的对于功用战争台敏感的API可以允许
一切的Java顺序以安全战争台无关的方式来运用这些功用, 在采用JNI之前, 开发者需求明确这些功用并不是曾经包含在Java标准类库中的, 在这篇文章
中, 我将会讲解JNI是如何任务的以及本地类型是如何映射到Java的类型和类库的。
  JNI任务原理
  在JNI中, 本地函数是通过一个独立的. c或. cpp文件来完成的(C++为JNI提供的界面会更简洁一些)。 当JVM调用该函数时, 它传递了
一个JNIEnv指针、一个jobject指针和通过Java方法定义的Java参数, JNI函数的方式如下:




 
JNIEXPORTvoidJNICALLJava_ClassName_MethodName   
(JNIEnv*env, jobjectobj)   {   //Methodnativeimplemenation  
 }
  env指针是一个包含了JVM接口的结构, 它包含了与JVM停止交互以及与Java对象协同任务所必需的函数, 示例中的JNI函数可以在本地数
组和Java数组类型之间、本地字符串和Java字符串类型之间停止转换, 其功用还包括对象的实例化、抛出异常等。 基本上您可以运用JNIEnv来完成所
有Java能做到的事情, 虽然要复杂很多。
  愈加正式的解释是这样的, 本地代码通过调用JNI的函数来访问JVM, 这是通过一个界面指针完成的(界面指针实践上是指向指针的指针), 该指针
指向一个指针数组, 数组中的每个指针都指向了一个界面函数, 而每个界面函数都是在数组中事后定义过的。
  本地方法将JNI界面指针当作一个参数, 假如在同一个Java线程中, 出现对该本地方法的多重调用, JVM则保证传递相同的界面指针到本地方
法。 不过, 一个本地方法可以被不同的Java线程调用, 因此也能够会收到不同的JNI界面指针。
  本地方法是通过System. loadLibrary方法加载的, 在以下的例子中, 类的初始化方法加载了一个指定平台的本地类库, 该类库定义了
本地方法:




packagepkg;   
classCls{   nativedoublef(inti, Strings);   static{   
System.cc霜 loadLibrary(pkg_Cls");   }   }
  System. loadLibrary方法的参数是一个类库的名称, 它可以由顺序员任意选取??闼樵蜃裱?桓霰曜嫉谋镜鼗?教ǖ姆绞嚼醋?焕嗫?的名称到一个本地类库的名称。 例如, 在Solaris操作零碎中会将pkg_Cls转换为libpkg_Cls. so, 而Win32零碎则会将同样的
pkg_Cls转换为pkg_Cls. dll。
  静态指针会依据它们的名字来停止解析, 一个本地方法的名称是依照组件停止衔接的, 它包含了:前缀“Java_”、一个分离的合法的类名称和一个
分离的方法名称。
  留意:微软的
JVM有相同的机制从Java调用本地Windows代码, 该机制被称为原始本地接口(Raw Native Interface (RNI))。
  基本类型, 比如整型、字符等等, 是在Java和本地代码间停止拷贝的, 而其他的自定义Java对象则是通过引用来传递的。
  这个表格展示了Java和本地代码之间的类型映射, 这些类型是可以互换的, 您可以在您运用int类型的位置运用jint类型, 当然反过去也一
样, 而且不需求任何类型转化。 但是, Java的字符串和数组类型和本地的字符串与数组类型之间的转换就比拟困难了, 假如您运用的jstring类型中出现
了字符“*”, 您的代码会造成JVM的崩溃, 以下的例子阐明了您应当如何正确运用字符串:
  



JNIEXPORTvoidJNICALLJava_ClassName_MethodName
  (JNIEnv*env, jobjectobj, jstringjavaString)   {   
//GetthenativestringfromJavastring   
constchar*nativeString=env-GetStringUTFChars(env, javaString, 0);
  printf("%s", nativeString);   
env-ReleaseStringUTFChars(env, javaString, nativeString);   }
  您需求运用界面指针env来操作Java对象。
  总结
  在您的顺序中运用JNI并不是一件容易的事情, 但是, JNI的功用和运用原有代码的能力将会为您的Java顺序添加更多的功用并且能胜任更多的
挑战, 假如需求关于JNI的更多信息, 可以访问JNI的主页。




欢迎光临 编程开发论坛 (http://bbs.lihuasoft.net/) Powered by Discuz! 6.0.0