To continue with the last blog post Eclipse to build the JNI development environment, now we analyze from the code point of view, C and Java mixed programming functions can be implemented.
With the Javah command, when you compile the. h header file, there will be at least two arguments for each function. JNIEnv and Jclass/jobject. wherein, when the native method is a static method (class method), the second parameter is Jclass, and when the native method is a member method, the second parameter is jobject. The rest of the parameters generate a specific signature based on the type of method parameter that you declare in the Java file. The JNI type defines the rules in the JNI header file as follows:
typedef Union JVALUE {
Jboolean z;
Jbyte B;
Jchar C;
Jshort S;
Jint i;
Jlong J;
Jfloat F;
Jdouble D;
Jobject l;
} Jvalue;
Corresponding Signature:
Java type |
JNI type |
Type signature |
Char |
Jchar |
C |
Int |
Jint |
I |
Long |
Jlong |
J |
Float |
Jfloat |
F |
Double |
Jdouble |
D |
Boolean |
Jboolean |
Z |
Byte |
Jbyte |
B |
Short |
Jshort |
S |
void |
|
V |
Class |
|
L fully qualified name, such as String, whose signature is ljava/lang/util/string; |
Array |
|
[type signature, such as [B] |
Jni.java file, corresponds to 7 native methods.
1. Call the C language printf function to output the fixed content.
public static native void print ();
2. Transfer to the specified string and output with the printf function.
public static native void print (String str);
3. Use C language to achieve the function of stitching string, and return to Java.
public static native string append (string str);
4. Incoming string, as a function of the Test class constructor, the C language invokes the constructor of the Java class, generates Jobject, and manipulates all methods and properties of the test class.
Public native void test (String test);
5. Pass in the object of the test class, manipulating all methods and properties of the test class.
Public native void test (test test);
6. Returns the passed-in byte array to the 16 feed string.
Public native String Tohex (byte[] test);
7. Returns the Passed-in string to a 16-byte array.
Public native byte[] tobytes (String test);
The complete sample code is as follows:
Com_flueky_jni_jni.h
/* Do isn't EDIT this file-it is machine generated/* #include <jni.h>/* Header for Class COM_FLUEKY_JNI_JNI * * * #i Fndef _included_com_flueky_jni_jni #define _INCLUDED_COM_FLUEKY_JNI_JNI #ifdef __cplusplus extern "C" {#endif/* Class
: Com_flueky_jni_jni * method:print * Signature: () V * * Jniexport void Jnicall java_com_flueky_jni_jni_print__
(JNIENV *, jclass); * * CLASS:COM_FLUEKY_JNI_JNI * method:print * Signature: (ljava/lang/string;) V/jniexport void Jnicall Jav
A_com_flueky_jni_jni_print__ljava_lang_string_2 (JNIEnv *, Jclass, jstring);
* * CLASS:COM_FLUEKY_JNI_JNI * method:append * Signature: (ljava/lang/string;) ljava/lang/string;
* * Jniexport jstring jnicall java_com_flueky_jni_jni_append (jnienv *, Jclass, jstring); * * CLASS:COM_FLUEKY_JNI_JNI * method:test * Signature: (ljava/lang/string;) V/jniexport void Jnicall Java
_com_flueky_jni_jni_test__ljava_lang_string_2 (JNIEnv *, Jobject, jstring); /*
* CLASS:COM_FLUEKY_JNI_JNI * method:test * Signature: (lcom/flueky/jni/test;) V/jniexport void Jnicall Java_c
Om_flueky_jni_jni_test__lcom_flueky_jni_test_2 (JNIEnv *, Jobject, jobject);
* * CLASS:COM_FLUEKY_JNI_JNI * Method:tohex * Signature: ([B) ljava/lang/string;
* * Jniexport jstring jnicall java_com_flueky_jni_jni_tohex (jnienv *, Jobject, Jbytearray); * * CLASS:COM_FLUEKY_JNI_JNI * method:tobytes * Signature: (ljava/lang/string;) [B * * Jniexport Jbytearray
ICALL java_com_flueky_jni_jni_tobytes (jnienv *, Jobject, jstring); #ifdef __cplusplus} #endif #endif
Main.cpp
* * * * main.cpp * * Created on:2016 March 22 * author:flueky/#include <stdio.h> #include "com_flueky_jni _jni.h "#include <jni.h> #include <stdlib.h> #include <string.h>/** * Operation object of test class/void Operate_test (jnienv *env, Jobject obj)
{///Based on object, get to Jclass jclass test_cls = Env->getobjectclass (obj);
Gets the member method ID jmethodid get_mid = env->getmethodid (Test_cls, "Gettest", "() ljava/lang/string;");
Callback member method Jstring test = (jstring) env->callobjectmethod (obj, get_mid);
Jsize len = env->getstringutflength (test);
Const char* str = env->getstringutfchars (test, jni_false);
char* result = (char*) malloc (sizeof (char) * (len + 1));
strcpy (result, str);
Sign End * (Result + len) = 0;
printf ("Gettest Output:%s\n", result);
Gets the Append method ID, calling the Append method jmethodid Append_mid = Env->getmethodid (Test_cls, "Append", "(ljava/lang/string;) V");
Env->callvoidmethod (obj, Append_mid, Env->newstringutf ("Append Test")); printf ("Append:append test\ n ");
Gets the member variable ID, class variable id getstaticfieldid jfieldid test_fid = Env->getfieldid (test_cls, "test", "ljava/lang/string;");
Gets the member variable value test = (jstring) env->getobjectfield (obj, test_fid);
Len = env->getstringutflength (test);
str = env->getstringutfchars (test, jni_false);
result = (char*) malloc (sizeof (char) * (len + 1));
strcpy (result, str);
Sign End * (Result + len) = 0;
printf ("Append results:%s\n", result);
Gets the static method id Jmethodid print_mid = env->getstaticmethodid (Test_cls, "print", "(icfzljava/lang/string;) V");
Call static method Env->callstaticvoidmethod (Test_cls, Print_mid, 1, ' C ', 1.2f, true, test);
Deletes obj object Env->deletelocalref (obj);
Env->deletelocalref (test);
} jniexport void Jnicall java_com_flueky_jni_jni_print__ (jnienv *env, Jclass cls) {printf ("little Brother 0217\n");} Jniexport void Jnicall java_com_flueky_jni_jni_print__ljava_lang_string_2 (jnienv *env, Jclass cls, jstring jstr) {JS
ize len = env->getstringutflength (JSTR); Const char* str = ENV->
Getstringutfchars (Jstr, Jni_false);
char* result = (char*) malloc (sizeof (char) * (len + 1));
strcpy (result, str);
Sign End * (Result + len) = 0;
printf ("Local output:%s", result); } jniexport jstring Jnicall java_com_flueky_jni_jni_append (jnienv *env, Jclass, jstring jstr) {//Get jstring length Jsize
Len = Env->getstringutflength (JSTR);
Jstring-string array const char* str = env->getstringutfchars (JSTR, Jni_false);
Allocation results string Space char* result = (char*) malloc (sizeof (char) * (len + 7 + 1));
String function processing strcpy (result, "append");
strcpy (Result + 7, str);
Sign End * (Result + 7 + len) = 0;
return Env->newstringutf (Result); /** * Operation Test class * * Jniexport void Jnicall java_com_flueky_jni_jni_test__ljava_lang_string_2 (jnienv *env, Jobject obj
, jstring jstr) {//test class Jclass test_cls = Env->findclass ("Com/flueky/jni/test"); The constructor method ID of the test class, the constructor name fixed <init>, the return type void Jmethodid Init_mid = Env->getmethodid (Test_cls, "<init>", "(
ljava/lang/string) V "); Create test Object JobJect test_obj = Env->newobject (Test_cls, Init_mid, JSTR);
Operate_test (env, test_obj); } jniexport void Jnicall java_com_flueky_jni_jni_test__lcom_flueky_jni_test_2 (jnienv *env, Jobject obj, Jobject test_ob
j) {Operate_test (env, test_obj);} Jniexport jstring jnicall Java_com_flueky_jni_jni_tohex (jnienv *env, Jobject jobj, Jbytearray jbytes) {//Get string length Jsiz
E len = env->getarraylength (jbytes);
Allocated memory char *result = (char *) malloc (sizeof (char) * (LEN * 2 + 1));
Allocating cached Memory jbyte* temp = (Jbyte *) malloc (sizeof (jbyte) * len);
Extract characters from a byte array env->getbytearrayregion (jbytes, 0, Len, temp);
Turn 16 to (int i = 0; i < len; i++) {* (Result + i * 2) = (* (temp + i) >> 4) & 0xf) + ' 0 ';
* (Result + I * 2 + 1) = (* (temp + i) & 0xf) + ' 0 ';
//Release cached memory free (temp);
* (Result + len * 2) = 0;
Generate jstring jstring str = ENV->NEWSTRINGUTF (result);
Free (result);
return str; } jniexport Jbytearray Jnicall java_com_flueky_jni_jni_tobytes (jnienv *env, Jobject jobj, jstring jstr) {//Get string length jsize len = env->getstringutflength (JSTR);
Allocating byte array space Jbytearray jbytes = Env->newbytearray (len * 2);
Convert jstring to a character array const Jchar * temp = Env->getstringchars (jstr, Jni_false);
Allocated memory char *result = (char *) malloc (sizeof (char) * (LEN * 2));
Turn 16 to (int i = 0; i < len; i++) {* (Result + i * 2) = (* (temp + i) >> 4) & 0xf) + ' 0 ';
* (Result + I * 2 + 1) = (* (temp + i) & 0xf) + ' 0 ';
///Fu Cun Word to byte array env->setbytearrayregion (jbytes, 0, Len * 2, (const jbyte *) result);
Free (result);
return jbytes;
}
Jni.java
Package com.flueky.jni;
public class Jni {static {system.loadlibrary ("jni_cpp"); /** * Native method, implemented in C language * * @author flueky zkf@yitong.com.cn * @date March 22, 2016 PM 4:23:00/public static Nativ
e void print (); /** * Native method, implemented in C language * * @author flueky zkf@yitong.com.cn * @date March 22, 2016 PM 6:10:43 * @param str/public s
tatic native void print (String str);
/** * Fu and return * * @author flueky zkf@yitong.com.cn * @date March 22, 2016 afternoon 6:12:03 * @param str * @return * *
public static native string append (string str); /** * Test Operation Test Class * * @author flueky zkf@yitong.com.cn * @date March 22, 2016 PM 6:16:06 * @param test/Public NA
tive void Test (String test); /** * Test Operation Test * * @author flueky zkf@yitong.com.cn * @date March 22, 2016 PM 6:16:59 * @param test/public NAT
ive void Test (test test);
/** * Transfer Test to 16 * * @author flueky zkf@yitong.com.cn * @date March 22, 2016 6:25:06 * @param test * @return * PublicNative String Tohex (byte[] test);
/** * Convert Test bytes * * @author flueky zkf@yitong.com.cn * @date March 22, 2016 afternoon 6:25:17 * @param test * @return * *
Public native byte[] tobytes (String test);
}
Test.java
Package com.flueky.jni;
public class Test {
private String test;
Public Test (String test) {
super ();
this.test = test;
}
Public String Gettest () {return
test;
}
public void append (String str) {
this.test = Test + "" + str;
}
/**
* Test calls static method, multi-parameter
*
* @author flueky zkf@yitong.com.cn
* @date March 22, 2016 PM 6:19:13
* @param STR/public
static void print (int i, char C, float F, boolean z, String test) {
System.out.println (string . Format ("Test printf:int =%d,char =%c,float =%.2f,boolean =%s,test =%s", I, C, F,
z + "", test));
}
Main.java
Package com.flueky.jni;
public class Main {public
static void Main (string[] args) {
jni.print ();//Small Fly elder brother 0217
jni.print ("csdn test"); Output: Csdn test
System.out.println (jni.append ("Flueky"));//Append flueky
jni jni = new Jni ();
Jni.test (New test ("little Brother 0217"));
Jni.test ("CSCN test");
System.out.println (New String (Jni.tobytes ("ABCDE")));
System.out.println (Jni.tohex ("12345". GetBytes ()));
}
Jni Method Description:
1. Get the Jclass object:
A.env->findclass ("Com/flueky/jni/test"); Note that this is not the signature of the class.
B.env->getobjectclass (obj);
2. Get method ID:
A.env->getmethodid (Test_cls, "Gettest", "() ljava/lang/string;"); /Get Member Method ID
B.env->getstaticmethodid (Test_cls, "print", "(icfzljava/lang/string;) V");//get static method ID
First argument, Jclass object, second parameter method name, third argument, method signature
3. Call Method:
A.env->callvoidmethod (obj, Append_mid, Env->newstringutf ("Append Test"))//Call member method
The first parameter is Jobject, the second parameter method ID, and then the argument, followed by the parameters in the Java method.
B.env->callstaticvoidmethod (Test_cls, Print_mid, 1, ' C ', 1.2f, true, test);/Call static method
The first parameter is Jclass, the second parameter method ID, and then the argument, followed by the parameters in the Java method.
4. Get Property ID:
A.env->getfieldid (test_cls, "test", "ljava/lang/string;"); /Get member Property ID
B.env->getstaticfieldid (test_cls, "test", "ljava/lang/string;"); /Gets the static property ID, which is not available in the program.
First parameter Jclass, second parameter property name, third parameter property signature
5. Get Property values:
A.env->getobjectfield (obj, test_fid);
First argument, jobject, second argument, property ID
B.env->getstaticobjectfield (Test_cls, Test_fid);
First argument, Jclass, second argument, property ID
6. Generating Jobject objects is usually passed from Java methods, as well as invoking Java construction methods to generate Jobject objects.
Gets the construction method Id,env->getmethodid (test_cls, "<init>", "(ljava/lang/string;) V");
The first parameter jclass, the second parameter constructs the method name (fixed <init>), the third parameter constructs the method signature (return type fixed void signature v)
Generate Jobject,env->newobject (Test_cls, Init_mid, JSTR);
The first parameter is Jclass, the second parameter constructs the method ID, followed by the parameters of the constructor in Java.
of the JNI function names called in 3 and 5 above, Char, Boolean, Byte, Int, Long, short, Float, Double, Object, void can be substituted for each other, except for void, where other types of functions have return values.
typedef jobject jstring;
typedef jobject Jarray;
typedef jarray Jbooleanarray;
typedef jarray Jbytearray;
typedef jarray Jchararray;
typedef jarray Jshortarray;
typedef jarray Jintarray;
typedef jarray Jlongarray;
typedef jarray Jfloatarray;
typedef jarray Jdoublearray;
typedef jarray Jobjectarray;
Referring to the definition in the JNI header file, the function of type object, the return value is Jobject and can be converted to the above type according to the actual situation.