您的位置:首页 > 编程语言 > Java开发

Java Native Interface笔记

2016-01-11 16:40 417 查看
最近在研究AndFix的动态更新原理,需要用到JNI,所以把JNI的基本知识点重新整理了一下,记录在这里,以免遗忘。

教程地址:https://www3.ntu.edu.sg/home/ehchua/programming/java/JavaNativeInterface.html

JNI数据类型:

Java原始类型:jint, jbyte, jshort, jlong, jfloat, jdouble, jchar, jboolean 分别对应 Java的int, byte, short, long, float, double, char和boolean

Java引用类型:jobject: java.lang.Object,他有如下的子类型

jclass: java.lang.Class

jstring: java.lang.String对应的是普通的Java对象

jthrowable: java.lang.Throwable

jarray: 一共有9中,8中Java原始类型对应的jarray,还有就是Java引用类型对应的jarray,也就是jobjectarray

C/C++语言可以直接操作Java原始类型的数据,但是对于Java引用类型的数据,必须要调用JNI环境接口提供的函数进行转换

在JNI中对Java中方法的成员的描述:

如果是Java类,那么用L表示,表示形式为”L”,点被正斜杠替换,比如String的表示就是”Ljava/lang/String”

如果是原始类型,那么

“I” for int,

“B” for byte,

“S” for short,

“J” for long,

“F” for float,

“D” for double,

“C” for char,

and “Z” for boolean

如果是数组,那么在前面加一个”[“,比如”[Ljava/lang/String”,就表示String[],

对Java方法的描述的格式是:

(parameters)return-type

return-type如果是void则用大写V表示

使用javap命令可以打印 Java类中的成员变量和方法的签名,比如:

javap -s -p TestJNICallBackMethod

下面要用到的词汇的定义

// ArrayType: jintArray, jbyteArray, jshortArray, jlongArray, jfloatArray, jdoubleArray, jcharArray, jbooleanArray

// PrimitiveType: int, byte, short, long, float, double, char, boolean

// NativeType: jint, jbyte, jshort, jlong, jfloat, jdouble, jchar, jboolean

在Java和Native程序之间传递String

JNI string相关的函数如下

// UTF-8 String (encoded to 1-3 byte, backward compatible with 7-bit ASCII)
// Can be mapped to null-terminated char-array C-string
const char * GetStringUTFChars(JNIEnv *env, jstring string, jboolean *isCopy);
// Returns a pointer to an array of bytes representing the string in modified UTF-8 encoding.
void ReleaseStringUTFChars(JNIEnv *env, jstring string, const char *utf);
// Informs the VM that the native code no longer needs access to utf.
jstring NewStringUTF(JNIEnv *env, const char *bytes);
// Constructs a new java.lang.String object from an array of characters in modified UTF-8 encoding.
jsize GetStringUTFLength(JNIEnv *env, jstring string);
// Returns the length in bytes of the modified UTF-8 representation of a string.
void GetStringUTFRegion(JNIEnv *env, jstring str, jsize start, jsize length, char *buf);
// Translates len number of Unicode characters beginning at offset start into modified UTF-8 encoding
// and place the result in the given buffer buf.

// Unicode Strings (16-bit character)
const jchar * GetStringChars(JNIEnv *env, jstring string, jboolean *isCopy);
// Returns a pointer to the array of Unicode characters
void ReleaseStringChars(JNIEnv *env, jstring string, const jchar *chars);
// Informs the VM that the native code no longer needs access to chars.
jstring NewString(JNIEnv *env, const jchar *unicodeChars, jsize length);
// Constructs a new java.lang.String object from an array of Unicode characters.
jsize GetStringLength(JNIEnv *env, jstring string);
// Returns the length (the count of Unicode characters) of a Java string.
void GetStringRegion(JNIEnv *env, jstring str, jsize start, jsize length, jchar *buf);
// Copies len number of Unicode characters beginning at offset start to the given buffer buf


传递原始类型的数组

NativeType * Get<PrimitiveType>ArrayElements(JNIEnv *env, ArrayType array, jboolean *isCopy);
void Release<PrimitiveType>ArrayElements(JNIEnv *env, ArrayType array, NativeType *elems, jint mode);
void Get<PrimitiveType>ArrayRegion(JNIEnv *env, ArrayType array, jsize start, jsize length, NativeType *buffer);
void Set<PrimitiveType>ArrayRegion(JNIEnv *env, ArrayType array, jsize start, jsize length, const NativeType *buffer);
ArrayType New<PrimitiveType>Array(JNIEnv *env, jsize length);
void * GetPrimitiveArrayCritical(JNIEnv *env, jarray array, jboolean *isCopy);
void ReleasePrimitiveArrayCritical(JNIEnv *env, jarray array, void *carray, jint mode);


访问对象的变量和方法

访问对象的实例变量涉及到的函数有:

jclass GetObjectClass(JNIEnv *env, jobject obj);
// Returns the class of an object.

jfieldID GetFieldID(JNIEnv *env, jclass cls, const char *name, const char *sig);
// Returns the field ID for an instance variable of a class.

NativeType Get<type>Field(JNIEnv *env, jobject obj, jfieldID fieldID);
void Set<type>Field(JNIEnv *env, jobject obj, jfieldID fieldID, NativeType value);
// Get/Set the value of an instance variable of an object
// <type> includes each of the eight primitive types plus Object.


访问类的静态变量涉及到的函数有:

jfieldID GetStaticFieldID(JNIEnv *env, jclass cls, const char *name, const char *sig);
// Returns the field ID for a static variable of a class.

NativeType GetStatic<type>Field(JNIEnv *env, jclass clazz, jfieldID fieldID);
void SetStatic<type>Field(JNIEnv *env, jclass clazz, jfieldID fieldID, NativeType value);
// Get/Set the value of a static variable of a class.
// <type> includes each of the eight primitive types plus Object.


调用实例方法和静态方法涉及到的函数有:

jmethodID GetMethodID(JNIEnv *env, jclass cls, const char *name, const char *sig);
// Returns the method ID for an instance method of a class or interface.

NativeType Call<type>Method(JNIEnv *env, jobject obj, jmethodID methodID, ...);
NativeType Call<type>MethodA(JNIEnv *env, jobject obj, jmethodID methodID, const jvalue *args);
NativeType Call<type>MethodV(JNIEnv *env, jobject obj, jmethodID methodID, va_list args);
// Invoke an instance method of the object.
// The <type> includes each of the eight primitive and Object.

jmethodID GetStaticMethodID(JNIEnv *env, jclass cls, const char *name, const char *sig);
// Returns the method ID for an instance method of a class or interface.

NativeType CallStatic<type>Method(JNIEnv *env, jclass clazz, jmethodID methodID, ...);
NativeType CallStatic<type>MethodA(JNIEnv *env, jclass clazz, jmethodID methodID, const jvalue *args);
NativeType CallStatic<type>MethodV(JNIEnv *env, jclass clazz, jmethodID methodID, va_list args);
// Invoke an instance method of the object.
// The <type> includes each of the eight primitive and Object.


调用superclass的实例方法

如果superclass的实例方法被子类重写了,此时你不想调用子类的实现,而是想调用superclass的实现

NativeType CallNonvirtual<type>Method(JNIEnv *env, jobject obj, jclass cls, jmethodID methodID, ...);
NativeType CallNonvirtual<type>MethodA(JNIEnv *env, jobject obj, jclass cls, jmethodID methodID, const jvalue *args);
NativeType CallNonvirtual<type>MethodV(JNIEnv *env, jobject obj, jclass cls,


创建对象和对象数组

在Native代码中调用构造函数去创建一个Java对象

method name为””,返回值为V

涉及到的函数有:

jclass FindClass(JNIEnv *env, const char *name);

jobject NewObject(JNIEnv *env, jclass cls, jmethodID methodID, ...);
jobject NewObjectA(JNIEnv *env, jclass cls, jmethodID methodID, const jvalue *args);
jobject NewObjectV(JNIEnv *env, jclass cls, jmethodID methodID, va_list args);
// Constructs a new Java object. The method ID indicates which constructor method to invoke

jobject AllocObject(JNIEnv *env, jclass cls);
// Allocates a new Java object without invoking any of the constructors for the object.


创建对象数组

涉及到的函数有

jobjectArray NewObjectArray(JNIEnv *env, jsize length, jclass elementClass, jobject initialElement);
// Constructs a new array holding objects in class elementClass.
// All elements are initially set to initialElement.

jobject GetObjectArrayElement(JNIEnv *env, jobjectArray array, jsize index);
// Returns an element of an Object array.

void SetObjectArrayElement(JNIEnv *env, jobjectArray array, jsize index, jobject value);
// Sets an element of an Object array.


局部引用和全局引用

局部引用:A local reference is created within the native method, and freed once the method exits. It is valid for the duration of a native method. You can also use JNI function DeleteLocalRef() to invalidate a local reference explicitly, so that it is available for garbage collection intermediately. Objects are passed to native methods as local references. All Java objects (jobject) returned by JNI functions are local references.

全局引用:A global reference remains until it is explicitly freed by the programmer, via the DeleteGlobalRef() JNI function. You can create a new global reference from a local reference via JNI function NewGlobalRef().
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: