Passing data to C language using JNI java

Source: Internet
Author: User

1. first, create the DataProvider class: [java] package com. pl. ndkpassdata; public class DataProvider {static {System. loadLibrary ("passdata"); // Load Library}/*** pass the int values in two java classes to the C language. After the C language completes processing, return the added result to java */public native int add (int x, int y ); /*** return the result of the C language processing subtraction operation to java */public static native int sub (int x, int y ); /*** pass the string in java to the C language. After the C language obtains the string in java, add a hello string */public native String getHell to the string. OString (String s);/*** pass an int array in java to the C language. After the C language completes processing this java array * add each element in the int array to + 10, then return the result to java */public native int [] getIntArr (int [] iNum);} 2. find it after creation. class: com_pl_ndkpassdata_DataProvider.h: [java]/* do not edit this file-it is machine generated */# include <JNI. h>/* Header for class com_pl_ndkpassdata_DataProvider */# ifndef _ Included_com_pl_ndkpassdata_DataProvider # define _ Included_com_pl_ndkpassdata_DataProvider # ifdef _ cplusplus extern "C" {# endif/** Class: com_pl_ndkpassdata_DataProvider * Method: add * Signature: (II) I */JNIEXPORT jint JNICALL inline (JNIEnv *, jobject, jint, jint);/** Class: com_pl_ndkpassdata_DataProvider * Method: sub * Signature: (II) I */JNIEXPORT jint JNICALL Java_com_pl_ndkpassdata_DataProvider_su B (JNIEnv *, jclass, jint, jint);/** Class: com_pl_ndkpassdata_DataProvider * Method: getHelloString * Signature: (Ljava/lang/String;) Ljava/lang/String; */JNIEXPORT jstring JNICALL values (JNIEnv *, jobject, jstring);/** Class: Optional * Method: getIntArr * Signature: ([I) [I */JNIEXPORT jintArray JNICALL values Data_DataProvider_getIntArr (JNIEnv *, jobject, jintArray); # ifdef _ cplusplus} # endif # The above is generated using the javah-jni command. 3. create a jni directory in the root directory of the project (level-1 with directories such as src and bin); 1. copy com_pl_ndkpassdata_DataProvider.h to the jni directory; 2. create Android in the jni directory. mk file and passdata. c file; (for c language. c and. the difference between the H file is that the function definition should be placed in. c, and. h only declares .) the following is Android. mk content: [java] LOCAL_PATH: = $ (call my-dir) include $ (CLEAR_VARS) LOCAL_MODULE: = passdata LOCAL_SRC_FILES: = passdata. c # liblog. c LOCAL_LDLIBS + =-llog include $ (BUILD_SHARED_LIBRARY) the following is passdata. c [java] # include <stdio. h> # include <Jni. h> # include <stdlib. h> # include "com_pl_ndkpassdata_DataProvider.h" # include <android/log. h> # define LOG_TAG "System. out. c "# define LOGD (...) _ android_log_print (ANDROID_LOG_DEBUG, LOG_TAG, _ VA_ARGS _) # define LOGI (...) _ android_log_print (ANDROID_LOG_INFO, LOG_TAG, _ VA_ARGS __) /*** converts a String in java to a pointer type that can point to a character in c. *** <jni. h> pointer function in: * jclass (* FindClass) (JNIEnv *, const char *); // get Class * jstring (* NewStringUTF) (JNIEnv *, const char *); // get a String object * jmethodID (* GetMethodID) (JNIEnv *, jclass, const char *, const char *); // method for getting the class * jobject (* CallObjectMethod) (JNIEnv *, jobject, jmethodID ,...); // call the Class Method * jsize (* GetArrayLength) (JNIEnv *, jarray); // obtain the array length * jbyte * (* GetByteArrayElements) (JNIEnv *, jbyteArray, jboolean *); // converts to byte pointer types available for c */char * Jstring2CStr (JNIEnv * env, jstring s ){ // JNIEnv *: pointer of the C language implementation of the struct structure of the Java Virtual Machine, including many jni Methods char * rtn = NULL; jclass classstring = (* env)-> FindClass (env, "java/lang/String"); // call the String class jstring strencode = (* env) in java-> NewStringUTF (env, "GB2312 "); // obtain the encoding format // obtain the method. Parameter 2: Specifies the class, parameter 3: method name, parameter 4 :( Ljava/lang/String;) is the parameter of getBytes; [B indicates that the returned value is a byte array jmethodID mid = (* env)-> GetMethodID (env, classstring, "getBytes", "(Ljava/lang/String ;) [B "); jbyteArray barr = (jbyteArray) (* env)-> CallObjectMethod (env, s, mid, strencode ); // equivalent to calling java's getBytes // get the length of the byte array jsize size = (* env)-> GetArrayLength (env, barr); jbyte * ba = (* env) -> GetByteArrayElements (env, barr, JNI_FALSE); if (size> 0) {rtn = (Char *) malloc (size + 1); // apply for a piece of memory // + "\ 0" memcpy (rtn, ba, size ); // copy the string rtn [size] = 0; // '\ 0'} (* env)-> ReleaseByteArrayElements (env, barr, ba, 0 ); // release the memory space return rtn;} JNIEXPORT jint JNICALL encode (JNIEnv * env, jobject obj, jint x, jint y) {LOGD ("add () x: % d, y: % d ", x, y); return x + y;} JNIEXPORT jint JNICALL Java_com_pl_ndkpassdata_DataProvider_sub (JNIEnv * env, jclass c Lazz, jint x, jint y) {LOGD ("sub () x: % d, y: % d", x, y); return x-y ;} JNIEXPORT jstring JNICALL values (JNIEnv * env, jobject obj, jstring s) {char * cs = Jstring2CStr (env, s); LOGD ("cs = % s", cs ); char carr [7] = {'', 'h', 'E', 'l', 'l', 'O', '\ 0'}; strcat (cs, carr); // concatenate LOGD ("new cs = % s", cs); LOGD ("end getHelloString ()"); return (* env)-> NewStringUTF (env, cs);} // jsize (* GetArrayLength) (JNIEnv *, jarray); // get the array length // jint * (* GetIntArrayElements) (JNIEnv *, jintArray, jboolean *) // convert to c available int pointer type JNIEXPORT jintArray JNICALL struct (JNIEnv * env, jobject obj, jintArray jarr) {jsize len = (* env)-> GetArrayLength (env, jarr); LOGD ("len = % d", len); jint * carr = (* env)-> GetIntArrayElements (env, jarr, JNI_FALSE); int I; for (I = 0; I <len; I ++ ){ * (Carr + I) + = 10;} LOGD ("end getIntArr ()"); return jarr;} ing implementation, which is generated using Cygwin. so library file. it's almost done. Don't forget to clean the project. Basically, this is done. The following is the test code: MainActivity. java [java] package com. pl. ndkpassdata; import android. OS. bundle; import android. app. activity; import android. view. view; import android. view. view. onClickListener; import android. widget. button; import android. widget. toast; public class MainActivity extends Activity implements OnClickListener {private Button bt1, bt2, bt3, bt4; private DataProvider provider; @ Override protected void onCreate (Bundle savedInstanceState) {super. onCreate (savedInstanceState); setContentView (R. layout. main); bt1 = (Button) this. findViewById (R. id. bt1); bt2 = (Button) this. findViewById (R. id. bt2); bt3 = (Button) this. findViewById (R. id. bt3); bt4 = (Button) this. findViewById (R. id. bt4); bt1.setOnClickListener (this); bt2.setOnClickListener (this); bt3.setOnClickListener (this); bt4.setOnClickListener (this); provider = new DataProvider ();} public void onClick (View v) {switch (v. getId () {case R. id. bt1: int result = provider. add (10, 10); Toast. makeText (this, "added result:" + result, 1 ). show (); break; case R. id. bt2: String str = provider. getHelloString ("pengliang"); Toast. makeText (this, str, 1 ). show (); break; case R. id. bt3: int [] arr = {7, 8, 9, 10, 6}; provider. getIntArr (arr); String arrtostr = "["; for (int I = 0; I <arr. length; I ++) {arrtostr + = arr [I] + "," ;}arrtostr + = "]"; Toast. makeText (this, arrtostr, 1 ). show (); break; case R. id. bt4: int subresult = DataProvider. sub (100, 24); Toast. makeText (this, "subtraction Result:" + subresult, 1 ). show (); break ;}} main. xml: [java] <LinearLayout xmlns: android = "http://schemas.android.com/apk/res/android" android: layout_width = "fill_parent" android: layout_height = "fill_parent" android: orientation = "vertical"> <Button android: id = "@ + id/bt1" android: layout_width = "fill_parent" android: layout_height = "wrap_content" android: text = "pass two intors to c code"/> <Button android: id = "@ + id/bt2" android: layout_width = "fill_parent" android: layout_height = "wrap_content" android: text = "Pass string to c code"/> <Button android: id = "@ + id/bt3" android: layout_width = "fill_parent" android: layout_height = "wrap_content" android: text = "pass the int array to the c code"/> <Button android: id = "@ + id/bt4" android: layout_width = "fill_parent" android: layout_height = "wrap_content" android: text = "Call static native METHOD"/> </LinearLayout>

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.