Learn some basic JNI knowledge

Source: Internet
Author: User

Watch the JNI video from Mr. Wang ziyou and learn the basic knowledge.

1. jnienv

The jnienv pointer can be used to operate Java code:

A. Create a Java object.

Newobject/newstring/New <type> Array

B. Call the Java object method.

Call <type> method/callstatic <type> Method

C. Obtain and set attributes of a Java object.

GET/set [Static] <type> Method

2. Common jtypes in JNI refer to classes in the Java environment.

typedef _jobject *jobject;typedef _jclass *jclass;typedef _jthrowable *jthrowable;typedef _jstring *jstring;typedef _jarray *jarray;typedef _jbooleanArray *jbooleanArray;typedef _jbyteArray *jbyteArray;typedef _jcharArray *jcharArray;typedef _jshortArray *jshortArray;typedef _jintArray *jintArray;typedef _jlongArray *jlongArray;typedef _jfloatArray *jfloatArray;typedef _jdoubleArray *jdoubleArray;typedef _jobjectArray *jobjectArray;

3. All jtypes are inherited from jobject.

class _jobject {};class _jclass : public _jobject {};class _jthrowable : public _jobject {};class _jstring : public _jobject {};class _jarray : public _jobject {};class _jbooleanArray : public _jarray {};class _jbyteArray : public _jarray {};class _jcharArray : public _jarray {};class _jshortArray : public _jarray {};class _jintArray : public _jarray {};class _jlongArray : public _jarray {};class _jfloatArray : public _jarray {};class _jdoubleArray : public _jarray {};class _jobjectArray : public _jarray {};

4. jobject

Jniexport void jnicall java_com_jue_testnative_testnative1_hello (jnienv *, jobject );

Jobject refers to a Java class instance that calls the native method in Java.

5. Methods for obtaining jclass

A. jclass findclass (const char * name)

B. jclass getobjectclass (jobject OBJ)

6. findclass searches for classes under classpath. You need to input the complete class name. Note that '/' is used between the package and the package '/'.

Jclass class_str = env-> findclass ("Java/lang/string ");

7. jfiledid/jmethodid

To obtain/set the value of a field in the natvie method or call a method, you must first obtain the ID of the corresponding field/method.

jfieldID GetFieldID(jclass clazz, const char *name, const char *sig) 
jmethodID GetMethodID(jclass clazz, const char *name, const char *sig)

Note that Sig is used to handle the uncertainty caused by function overloading.

And then get it by ID

jobject GetObjectField(jobject obj, jfieldID fieldID) 
jobject CallObjectMethod(jobject obj, jmethodID methodID, ...)

8. Sin signature meaning details

Type Corresponding Signature
Boolean Z
Byte B
Char C
Short S
Int I
Long L
Float F
Double D
Void V
String Ljava/lang/string
Array [Ljava/lang/Object
Method (Para S1, para S2)
Return Value Signature

9. The javap-s command tool can view the signature of a class method.

Javap-s XXX. Class

10. Call the Java method

A. jnienv provides the call <type> method, callstatic <type> method, callnonvirtual <type> method function (which can implement the function of the subclass object to call the parent class method ).

B. Three Methods for calling the instance method

1> call <type> method (jobject OBJ, jmethodid ID ,...);

boolean funcation(int i, double d, char c) {}env->CallBooleanMethod( obj, id_function , 100L, 3.44, L'3');

Note that the int type in Java is a long integer in the C ++ environment. L '3' is a wide character in C ++

2> call <type> methodv (jobject OBJ, jmethodid, va_list lst );

3> call <type> methoda (jobject OBJ, jmethodid, jvalue * V );

Jvalue is a consortium

typedef union jvalue {    jboolean z;    jbyte    b;    jchar    c;    jshort   s;    jint     i;    jlong    j;    jfloat   f;    jdouble  d;    jobject  l;} jvalue;

jvalue *args = new jvalue[3];args[0].i = 100L;args[1].d = 3.44;args[2].c = L'3';env->CallBooleanMethodA(obj, id_funcation, args);delete [] args;

11. Create a Java object

A. Method-newobject

Use newobject to create a Java object.

Jobject newobject (jclass clazz, jmethodid methodid ,...)

The name of the constructor that needs to be active first, and the method name is set to <init>. In addition, the returned signature is void.

Jmethodid getmethodid (jclass clazz, const char * Name,

Const char * sig)

Example:

jclass class_date = env->FindClass("java/util/Date");jmethodID method_id = env->GetMethodID(class_date,"<init>","()V");jobject now = env->NewObject(class_date, method_id);

B. Method-allocobject

12. Java string <----> C ++ string

A. in Java, the string object is a Unicode (UTF-16) code, and each character occupies two bytes, both Chinese and English.

B. you can use the JNI interface to convert the string in Java into a wide string in C/C ++, Java can also pass a UTF-8 string (char *) to C/C ++.

C. In turn, C ++ can create a Java-end object by setting a wide string or a UTF-8 string.

13. Get the Java string

A. Obtain the Java string related to a jstring object.

Method Function
Getstringchars Get the UTF-16-encoded wide string (char *)
Getstringutfchars Get a UTF-8-encoded string (char *)

const jchar *GetStringChars(jstring str, jboolean *isCopy) {    return functions->GetStringChars(this,str,isCopy);}

When using these two methods, you must use releasestringchars or releasestringutfchars to release the copied memory or reference the Java object.

    void ReleaseStringChars(jstring str, const jchar *chars) {        functions->ReleaseStringChars(this,str,chars);    }

The first parameter indicates the source of the local string, and the second parameter indicates the local string to be released.

You can also use the following method to increase the possibility of returning Java objects in JVM, but it is still possible to return copies of corresponding Java strings.

This method does not have the corresponding getstringutfcritical, because the Java string uses the UTF-16, to convert to the UTF-8 encoded string originally needs a copy action.

    const jchar * GetStringCritical(jstring string, jboolean *isCopy) {        return functions->GetStringCritical(this,string,isCopy);    }    void ReleaseStringCritical(jstring string, const jchar *cstring) {        functions->ReleaseStringCritical(this,string,cstring);    }

Getstringcritical and releasestringcritical cannot use other JNI functions (such as allocating other JVM objects) or any code that causes the current thread to wait. Otherwise, the JVM will be deadlocked.

In another method, this method directly copies the Java string to the C/C ++ string array. Before calling, there must be a string allocated by C/C ++.

    void GetStringRegion(jstring str, jsize start, jsize len, jchar *buf) {        functions->GetStringRegion(this,str,start,len,buf);    }    void GetStringUTFRegion(jstring str, jsize start, jsize len, char *buf) {        functions->GetStringUTFRegion(this,str,start,len,buf);    }

14. Generate a Java string

    jstring NewString(const jchar *unicode, jsize len) {        return functions->NewString(this,unicode,len);    }
    jstring NewStringUTF(const char *utf) {        return functions->NewStringUTF(this,utf);    }

Note: newstringutf does not contain the string length, because an additional sign '\ 0' is appended to the end of the string in C/C ++ '.

How to obtain the length of a string

    jsize GetStringLength(jstring str) {        return functions->GetStringLength(this,str);    }    jsize GetStringUTFLength(jstring str) {        return functions->GetStringUTFLength(this,str);    }

15. arrays are divided into two types

A. array of basic types.

B. array of object type (object.

There is a function that is used in two different Arrays:

    jsize GetArrayLength(jarray array) {        return functions->GetArrayLength(this,array);    }

16. Process arrays of Basic Types

Similar to processing strings

Get <type> arrayelements, which can convert an array of Basic Java types to an array in C/C ++, and copy a copy of the local code, you can also direct the pointer to Java back to the local code.

Required

Release <type> arrayelements

    void ReleaseIntArrayElements(jintArray array,                                 jint *elems,                                 jint mode) {        functions->ReleaseIntArrayElements(this,array,elems,mode);    }

Mode:

0: update the Java array and release the C/C ++ array.

Jni_commit: updates the Java array but does not release the C/C ++ array.

Jni_abort: the Java array is not updated and the C/C ++ array is released.

Functions similar to getstringutfcritical: Functions Added to directly return pointers to Java arrays.

    void * GetPrimitiveArrayCritical(jarray array, jboolean *isCopy) {        return functions->GetPrimitiveArrayCritical(this,array,isCopy);    }    void ReleasePrimitiveArrayCritical(jarray array, void *carray, jint mode) {        functions->ReleasePrimitiveArrayCritical(this,array,carray,mode);    }

Get <type> arrayregion is similar to the getstringregion function: There is no release method, because we copy

    void GetIntArrayRegion(jintArray array,                           jsize start, jsize len, jint *buf) {        functions->GetIntArrayRegion(this,array,start,len,buf);    }

Set <type> arrayregion can assign values to the Java array elements in the specified range using the elements in C ++.

    void SetIntArrayRegion(jintArray array, jsize start, jsize len,                           const jint *buf) {        functions->SetIntArrayRegion(this,array,start,len,buf);    }

Create a basic java Array

<Type> array new <type> array (jsize size). If the length is specified, an array of the corresponding Java basic type is returned.

17. process an array of Object Types

JNI does not convert an array of Java object types to jobject [] in C ++. Instead, get/setobjectarrayelement is used to operate the Java object array.

    jobject GetObjectArrayElement(jobjectArray array, jsize index) {        return functions->GetObjectArrayElement(this,array,index);    }    void SetObjectArrayElement(jobjectArray array, jsize index,                               jobject val) {        functions->SetObjectArrayElement(this,array,index,val);    }

You do not need to release resources in the preceding method.

You can create an array of A Class Based on the array length and initial value.

    jobjectArray NewObjectArray(jsize len, jclass clazz,                                jobject init) {        return functions->NewObjectArray(this,len,clazz,init);    }

18. Java object reference in JNI

When an object created in JVM is uploaded to the local C/C ++ code, a reference is generated. According to the JVM garbage collection mechanism, as long as the reference exists, it will not trigger the collection of the reference pointing to the object.

These references are divided into three types:

Global Reference: Global Reference

Local reference

Weak global reference: weak global reference

Local reference: it is the most common reference. Local reference is only valid in native functions. The existence of a local reference will prevent it from pointing to object recycling.

Global Reference:

Can span multiple threads

Valid in multiple navtive methods,

When a global reference exists, Java objects referenced by it are blocked from being recycled in JVM.

The global reference is not automatically created by JNI.

Call the newglobalref function to create a global reference for display, and call the releaseglobalref function for release.

Weak global reference:

Similar to global references, the creation and release operations must be performed by programmers.

Multiple Threads, valid in multiple native methods.

Difference: This reference does not prevent JVM from recycling the reference it points.

Newweakglobalref and releaseweakglobalref create and release references.

19. issameobject has a special function in the weak global reference.

Pass null to the object to be judged to determine whether the Java object pointed to by the weak global reference is recycled.

20. cache jfieldid, jmethodid.

A. query jfieldid by method name + signature. The jmethod overhead is very large.

B. cache method:

1. cache when using it. (Caching at the point of use)

Use static local variables to save the queried IDs, so that they are not queried at each call, but only once.

2. Cache during Java class initialization. (Caching at class's inititalizer)

This method re-calls the native method to re-calculate the ID when the JVM class is loaded and reloaded.

public class TestNative{static {initNativeIDs();}static natvie void initNativeIDs();int propInt = 0;}

JNIEXPORT void JNICALL  Java_TestNative_initNativeIDs(JNIEnv *env, jobject object){......g_propInt_id = GetFieldID(clazz,  "propInt", "I" );}

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.