本文是基于维基百科中JNI英文文档翻译而来。
E文文档地址:http://en.wikipedia.org/wiki/Java_Native_Interface
一、缺陷
1.使用JNI细小的错误都能让这个JVM不稳定,并且这些错误很难再现和调试
2.使用JNI的应用失去了JAVA本身提供的不同平台的可移植性。
3.JNI 框架不提供自动的垃圾回收机制,所以这部分代码要考虑内存的释放
4.在linux 和solaris 平台,信号量过滤器会认为本地代码会处理信号量比JVM更好,所以如果本地代码注册自己为单处理(signal handler),他们就能够拦截到JVM的信号量。
5.在没有处理的异常中所有可能成为结果的都可能出现一些中断(比如空指针,除数为零),为了在中断到达JVM之前处理这些情况,在windows 平台,在try/catch 块中SHE(Structured Exception Handing)可能被使用去包装本地代码,以便获得机器(CPU/FPU)生成的软中断。
6.编码相关的方法是通过UTF-8修改而来:NewStringUTF, GetStringUTFLength, GetStringUTFChars, ReleaseStringUTFChars, GetStringUTFRegion,不是标准的UTF-8方法。程序应该使用NewString,GetStringChars,ReleaseStringChars, GetStringRegion, GetStringCritical, ReleaseStringCritical 方法,这些方法使用UTF-16LE 小尾端(little-endian)架构和UTF-16BE大尾端架构,然后用UTF-16到标准的UTF-8的转换。
二、类型映射
JNI基本类型和本地代码的类型映射
unsigned char | jboolean | unsigned 8 bits | Z |
signed char | jbyte | signed 8 bits | B |
unsigned short | jchar | unsigned 16 bits | C |
short | jshort | signed 16 bits | S |
long | jint | signed 32 bits | I |
long long |
jlong | signed 64 bits | J |
float | jfloat | 32 bits | F |
double | jdouble | 64 bits | D |
void | V |
以上基本数据类型和本地代码可以直接使用,但是对于字符串和数组来说需要经过相应的转换才行
字符串
JNIEXPORT void JNICALL Java_ClassName_MethodName (JNIEnv *env, jobject obj, jstring javaString) { // printf("%s", javaString); // INCORRECT: Could crash VM! // Correct way: Create and release native string from Java string const char *nativeString = (*env)->GetStringUTFChars(env, javaString, 0); printf("%s", nativeString); (*env)->ReleaseStringUTFChars(env, javaString, nativeString); }
数组
JNIEXPORT jint JNICALL Java_IntArray_sumArray (JNIEnv *env, jobject obj, jintArray arr) { jint buf[10]; jint i, sum = 0; // This line is necessary, since Java arrays are not guaranteed // to have a continuous memory layout like C arrays. env->GetIntArrayRegion(arr, 0, 10, buf); for (i = 0; i < 10; i++) { sum += buf[i]; } return sum; }
关于JNIEnv
JNIEnv 是JNI方法的第一个参数,他提供了JNI环境和本地环境的相互作用,JNIEnv指针可以保存,但是之在当前线程才是合法的,其它线程必须先调用AttachCurrentThread()把当前依附到JVM上然后得到一个JNIEnv 的指针,之后这个本地线程就像一个JAVA线程一样工作了, 调用DetachCurrentThread()解除依附。
JNIEnv *env; (*g_vm)->AttachCurrentThread (g_vm, (void **) &env, NULL); (*g_vm)->DetachCurrentThread (g_vm);
相关推荐
### JNI数据类型转换详解 JNI(Java Native Interface)作为Java平台与本地代码(如C/C++)之间的桥梁,其核心功能之一就是实现不同语言间的数据类型转换。在JNI编程中,理解并掌握Java数据类型与C/C++数据类型之间...
08_12_JNI_02_jni数据类型&属性方法08_12_JNI_02_jni数据类型&属性方法08_12_JNI_02_jni数据类型&属性方法08_12_JNI_02_jni数据类型&属性方法08_12_JNI_02_jni数据类型&属性方法08_12_JNI_02_jni数据类型&属性方法08...
虽然JNI调用有额外的开销,但通过合理的优化,如减少不必要的类型转换和内存复制,可以提高整体性能。 综上所述,JNI是Java与C++交互的重要桥梁。通过理解JNI的工作原理,以及如何映射Java类和C++类,我们可以有效...
- **类型映射**: Java中的原始类型可以直接映射到C/C++的基本类型上,而复杂类型则需要通过JNI函数进行转换。 #### 三、结构体在JNI中的使用 在C/C++中,结构体是一种非常常用的数据组织形式。在JNI中,如果要在C/...
这个压缩包中的示例工程包含了Java和C++的代码,可以作为学习和实践JNI处理不同类型数据的参考。你可以直接运行这些代码,观察其工作原理。同时,提供的参考资料也会帮助你深入理解JNI的工作机制和最佳实践。 总之...
`jni_md.h`则是特定平台的本地数据类型和函数定义,它根据目标平台(如Windows、Linux、Android等)的不同而有所不同。通常,`jni_md.h`被`jni.h`包含,并且在编译时由JDK自动选择合适的版本。 Java调用C和C++函数...
首先,`jni.h`是JNI的主要接口头文件,包含了所有JNI的函数声明和数据类型定义。当你在C或C++程序中使用JNI时,需要包含这个头文件。`jni.h`提供了大量的函数原型,这些函数用于在Java虚拟机(JVM)和本地代码之间...
JNI提供了一套标准的类型映射,用于在Java和本地代码之间传递数据。例如,Java的`int`对应于C/C++的`jint`,`String`对应于`jobject`,并需要通过`NewStringUTF`和`GetStringUTFChars`等函数进行操作。对于数组,有...
JNI定义了一套类型映射规则,确保Java和本地代码之间的数据类型一致。例如: - Java中的基本数据类型和String类型映射到相应的C/C++类型。 - Java的数组和对象如何传递和处理。 #### 4. JNI 中的字符串、数组和对象...
Java Native Interface (JNI) 是Java平台的一个重要组成部分,自Java 1.1开始引入...通过理解JNI的基本原理和类型映射,以及熟练使用`JNIEnv`结构,开发者可以有效地实现Java和本地代码的交互,提高软件的功能和性能。
方法的参数和返回值类型需要按照JNI的类型映射规则进行转换。 表A列出了Java类型及其对应的本地C/C++类型,例如,`boolean`映射为`jboolean`,`int`映射为`jint`,`Object`映射为`jobject`,等等。有些类型可以直接...
`jni.pas`通常会封装JNI的C头文件(如`jni.h`)中的函数和数据类型,使得Delphi程序员可以更方便地在Delphi程序中使用JNI接口。 描述中提到的"包含文件 jni.pas JNI_MD.INC",`JNI_MD.INC`是一个平台特定的包含文件...
在JNI中,传递基本类型(如int、float等)相对简单,直接通过参数即可。然而,处理复杂对象,如字符串、数组或自定义类,需要更多的步骤。对于Java字符串,我们可以使用`env->NewStringUTF`创建一个新的本地字符串,...
1. **JNI数据类型**:定义了一系列用于在Java和本地代码之间传递数据的类型,如`jobject`, `jclass`, `jmethodID`, `JNIEnv*`等。例如,`JNIEnv`指针是一个指向结构体的指针,包含了执行JNI操作所需的函数指针。 2....
Java与JNI数据类型对照表,可能有许多不足之处,请大家参考一下。
6. **类型映射**: JNI提供了一套映射规则,将Java数据类型与C/C++数据类型对应起来,如`jobject`对应Java对象,`jint`对应Java的`int`。 7. **方法ID和字段ID**: 调用Java方法和访问字段需要获取相应的ID。`Find...
这个"android C/C++ JNI普通数据类型 测试工程"是用于演示如何在C/C++与Java之间传递和操作基本数据类型的一个实例。在本文中,我们将深入探讨JNI中的数据类型转换以及如何在C/C++代码和Java代码之间使用它们。 ...
JNI在Java和本地代码之间进行数据传递时,需要进行类型映射。这个文件很可能详细列出了Java数据类型和C/C++数据类型之间的对应关系,例如,`jint`对应于Java的`int`,`jdouble`对应于`double`,`jobject`对应于指向...