An example of mastering JNI development

Source: Internet
Author: User
Tags types of functions

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-&GT
	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&gt, 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-&GT;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.

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.