Android的jni的调用C,C++的几个应用(基本类型,数组,类(结构体))

mousefat 贡献于2012-12-25

作者 suker  创建于2011-05-09 07:11:00   修改者TOSHIBA  修改于2012-02-11 13:24:00字数16538

文档摘要:开始正题啦,前些天在研究Andorid中Jni(JavaNativeInterface)的使用,主要是在android中调用C、C++的方法,在网上也搜集了一些文档,源码等资料,非常感谢网友的提供的宝贵经验。也是写下这个文章,希望可以帮助正在做这方面应用网友们,jni使用c语言。
关键词:

Android的jni的调用C,C++的几个应用(基本类型,数组,类(结构体)) 开始正题啦,前些天在研究Andorid中Jni(Java Native Interface)的使用, 主要是在android中调用C、C++的方法,在网上也搜集了一些文档,源码等资料,非常感谢网友的提供的宝贵经验。 也是写下这个文章,希望可以帮助正在做这方面应用网友们,jni使用c语言。 一、首先软件环境要搭配好,本人使用的环境是 Android2.2的SDK+NDK4b,linux下的编译环境 1. Windows XP 2. VMware 7.1.3 build-324285 + Ubuntu 9.04中文版 3. Android SDK 2.2 4. Android NDK r4b Linux版(crystax),加入支持C++ exceptions, RTTI and Standard C++ Library http://www.crystax.net/android/ndk-r4.php http://www.crystax.net/data/android-ndk-r4-linux-x86-crystax-4.tar.bz2 5. Eclipse Version: 3.5.2 eclipse3.5.2官方下载地址 http://archive.eclipse.org/eclipse/downloads/drops/R-3.5.2-201002111343/eclipse-SDK-3.5.2-win32.zip 6. 二、配置好eclipse,并加入androiddSDK,然后通过eclipse建立一个android工程,搭建android的jni框架 1. Eclipse File->New->Android Project 如果此地没有Android Project,可以通过File->New->Project...,在弹出的对话框中,选择(Android) 以下几项填写,其他的默认即可 Project name: AndroidJni Build Target: Android 2.2 Application name: AndroidJni Package name: com.jni Create Activity: AndroidJni Min SDK Version: 8 点击Finish即可 此时,我们就可以看到我们的项目了 在src->com.jni下自动生成的AndroidJni.java内容如下 view plaincopy to clipboardprint? ·········10········20········30········40········50········60········70········80········90········100·······110·······120·······130·······140·······150 package com.jni; import android.app.Activity; import android.os.Bundle; public class AndroidJni extends Activity { /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); } } 我们在这里新建立一个class,比如命名jernymyjni, 这个作为我们的Jni的所有接口处,作为测试设计了基本类型,数组,和类(结构体),结构体数组等。 代码如下 view plaincopy to clipboardprint? ·········10········20········30········40········50········60········70········80········90········100·······110·······120·······130·······140·······150 package com.jni; // jernymy use c style for var name public class jernymyjni { char chChar; // char use ch token // short wShort; // short use w token, short same as int int nInt; // int use n token String sString; // String use s token /*-------- jernymy for base type declaration start --------*/ /* * The char process method GetChar * @param char chInput : the input char for process * @return(char) : input char (chInput) upper or lower * @author : jernymy * @date : 20110508 * */ public native char GetChar(char chInput); /* * The char process method SetChar * @param char chInput : set the input char * @return(int) : status, 0-OK, other-Error * @author : jernymy * @date : 20110508 * */ public native int SetChar(char chInput); /* * The int process method GetInt * @param int nAdd1 : add one * @param int nAdd2 : add other * @return(int) : sum of two add var * @author : jernymy * @date : 20110508 * */ public native int GetInt(int nAdd1, int nAdd2); /* * The int process method SetInt * @param int nSet : set one int data * @return(int) : status, 0-OK, other-Error * @author : jernymy * @date : 20110508 * */ public native int SetInt(int nSet); /* * The String process method GetStr * @return(String) : the string for use * @author : jernymy * @date : 20110508 * */ public native String GetStr(); /* * The String process method PrcsStr * @param String sInput : the input String for process * @return(String) : the process of the input String * @author : jernymy * @date : 20110508 * */ public native String PrcsStr(String sInput); /* * The String process method PrcsStr * @param String sSet : the set String * @return(int) : status, 0-OK, other-Error * @author : jernymy * @date : 20110508 * */ public native int SetStr(String sSet); /*-------- jernymy for base type declaration end --------*/ /*-------- jernymy for array type declaration start --------*/ /* * The char array process method GetCharArray * @param char chSet : the chSet char for process * @return(char[]) : char array, upper and lower * @author : jernymy * @date : 20110508 * */ public native char[] GetCharArray(char chSet); /* * The char array process method SetCharArray * @param char[] chSet : the chSet char array for process * @return(int) : status, 0-OK, other-Error * @author : jernymy * @date : 20110508 * */ public native int SetCharArray(char[] chSet); /* * The int array process method GetIntArray * @param int[] nAdd1 : add one array * @param int[] nAdd2 : add other array * @return(int[]) : sum array of two add array var * @author : jernymy * @date : 20110508 * */ public native int[] GetIntArray(int[] nAdd1, int[] nAdd2); /* * The int array process method SetIntArray * @param int[] nSet : set one int array data * @return(int) : status, 0-OK, other-Error * @author : jernymy * @date : 20110508 * */ public native int SetIntArray(int[] nSet); /* * The String array process method GetStrArray * @return(String[]) : String array with null parameter * @author : jernymy * @date : 20110508 * */ public native String[] GetStrArray(); /* * The String array process method PrcsStrArray * @param String sSet : the string with " " token sSet * @return(String[]) : ervey string by " " token * @author : jernymy * @date : 20110508 * */ public native String[] PrcsStrArray(String sSet); /* * The String array process method SetStrArray * @param String[] sSet : set the string array * @return(int) : status, 0-OK, other-Error * @author : jernymy * @date : 20110508 * */ public native int SetStrArray(String[] sSet); /*-------- jernymy for array type declaration end --------*/ /*-------- jernymy for class(struct) type declaration start --------*/ /* * The jernymyjni class(struct) process method GetClass * @param int nIdx : get class data by index * @return(jernymyjni) : status, 0-OK, other-Error * @author : jernymy * @date : 20110508 * */ public native jernymyjni GetClass(int nIdx); /* * The jernymyjni class(struct) process method SetClass * @param jernymyjni cClass : set class data by class index * @return(int) : status, 0-OK, other-Error * @author : jernymy * @date : 20110508 * */ public native int SetClass(jernymyjni cClass); /*-------- jernymy for class(struct) type declaration end --------*/ /*-------- jernymy for class(struct) array type declaration start --------*/ /* * The jernymyjni class(struct) array process method GetClassArray * @return(jernymyjni[]) : class array data * @author : jernymy * @date : 20110508 * */ public native jernymyjni[] GetClassArray(); /* * The jernymyjni class(struct) array process method SetClassArray * @param jernymyjni[] cNcomnAry : set class array data * @return(int) : status, 0-OK, other-Error * @author : jernymy * @date : 20110508 * */ public native int SetClassArray(jernymyjni[] acClassAry); /*-------- jernymy for class(struct) array type declaration end --------*/ static { System.loadLibrary("jernymyjni"); // jernymy here is the so name } } 通过eclipse的生成对应的class文件,会在AndroidJni\bin下生成所有的文件 然后进入windowsXP的command模式 开始->运行->cmd 到我们的项目的所在目录,我的目录为 运行javah,得到对应的jni的头文件 E:\work\jave\workspace\AndroidJni>javah -classpath bin com.jni.jernymyjni E:\work\jave\workspace\AndroidJni> 此时会在当前目录下生成一个com_jni_jernymyjni.h,好了,就是它了,接下来开始编写它对应的c文件了。 为了符合android的文档规范,我们需要在当前目录(AndroidJni)下先建立一个jni目录,然后再建立一个Android.mk 然后把com_jni_jernymyjni.h文件copy到jni目录下。 E:\work\jave\workspace\AndroidJni>cd jni E:\work\jave\workspace\AndroidJni\jni>dir 驱动器 E 中的卷是 work 卷的序列号是 1C8F-CA73 E:\work\jave\workspace\AndroidJni\jni 的目录 2011-05-08 23:09 . 2011-05-08 23:09 .. 2011-05-08 23:08 0 Android.mk 2011-05-08 22:58 3,802 com_jni_jernymyjni.h 2 个文件 3,802 字节 2 个目录 10,864,427,008 可用字节 E:\work\jave\workspace\AndroidJni\jni> com_jni_jernymyjni.h的文件内容 view plaincopy to clipboardprint? ·········10········20········30········40········50········60········70········80········90········100·······110·······120·······130·······140·······150 /* DO NOT EDIT THIS FILE - it is machine generated */ #include /* Header for class com_jni_jernymyjni */ #ifndef _Included_com_jni_jernymyjni #define _Included_com_jni_jernymyjni #ifdef __cplusplus extern "C" { #endif /* * Class: com_jni_jernymyjni * Method: GetChar * Signature: (C)C */ JNIEXPORT jchar JNICALL Java_com_jni_jernymyjni_GetChar (JNIEnv *, jobject, jchar); /* * Class: com_jni_jernymyjni * Method: SetChar * Signature: (C)I */ JNIEXPORT jint JNICALL Java_com_jni_jernymyjni_SetChar (JNIEnv *, jobject, jchar); /* * Class: com_jni_jernymyjni * Method: GetInt * Signature: (II)I */ JNIEXPORT jint JNICALL Java_com_jni_jernymyjni_GetInt (JNIEnv *, jobject, jint, jint); /* * Class: com_jni_jernymyjni * Method: SetInt * Signature: (I)I */ JNIEXPORT jint JNICALL Java_com_jni_jernymyjni_SetInt (JNIEnv *, jobject, jint); /* * Class: com_jni_jernymyjni * Method: GetStr * Signature: ()Ljava/lang/String; */ JNIEXPORT jstring JNICALL Java_com_jni_jernymyjni_GetStr (JNIEnv *, jobject); /* * Class: com_jni_jernymyjni * Method: PrcsStr * Signature: (Ljava/lang/String;)Ljava/lang/String; */ JNIEXPORT jstring JNICALL Java_com_jni_jernymyjni_PrcsStr (JNIEnv *, jobject, jstring); /* * Class: com_jni_jernymyjni * Method: SetStr * Signature: (Ljava/lang/String;)I */ JNIEXPORT jint JNICALL Java_com_jni_jernymyjni_SetStr (JNIEnv *, jobject, jstring); /* * Class: com_jni_jernymyjni * Method: GetCharArray * Signature: (C)[C */ JNIEXPORT jcharArray JNICALL Java_com_jni_jernymyjni_GetCharArray (JNIEnv *, jobject, jchar); /* * Class: com_jni_jernymyjni * Method: SetCharArray * Signature: ([C)I */ JNIEXPORT jint JNICALL Java_com_jni_jernymyjni_SetCharArray (JNIEnv *, jobject, jcharArray); /* * Class: com_jni_jernymyjni * Method: GetIntArray * Signature: ([I[I)[I */ JNIEXPORT jintArray JNICALL Java_com_jni_jernymyjni_GetIntArray (JNIEnv *, jobject, jintArray, jintArray); /* * Class: com_jni_jernymyjni * Method: SetIntArray * Signature: ([I)I */ JNIEXPORT jint JNICALL Java_com_jni_jernymyjni_SetIntArray (JNIEnv *, jobject, jintArray); /* * Class: com_jni_jernymyjni * Method: GetStrArray * Signature: ()[Ljava/lang/String; */ JNIEXPORT jobjectArray JNICALL Java_com_jni_jernymyjni_GetStrArray (JNIEnv *, jobject); /* * Class: com_jni_jernymyjni * Method: PrcsStrArray * Signature: (Ljava/lang/String;)[Ljava/lang/String; */ JNIEXPORT jobjectArray JNICALL Java_com_jni_jernymyjni_PrcsStrArray (JNIEnv *, jobject, jstring); /* * Class: com_jni_jernymyjni * Method: SetStrArray * Signature: ([Ljava/lang/String;)I */ JNIEXPORT jint JNICALL Java_com_jni_jernymyjni_SetStrArray (JNIEnv *, jobject, jobjectArray); /* * Class: com_jni_jernymyjni * Method: GetClass * Signature: (I)Lcom/jni/jernymyjni; */ JNIEXPORT jobject JNICALL Java_com_jni_jernymyjni_GetClass (JNIEnv *, jobject, jint); /* * Class: com_jni_jernymyjni * Method: SetClass * Signature: (Lcom/jni/jernymyjni;)I */ JNIEXPORT jint JNICALL Java_com_jni_jernymyjni_SetClass (JNIEnv *, jobject, jobject); /* * Class: com_jni_jernymyjni * Method: GetClassArray * Signature: ()[Lcom/jni/jernymyjni; */ JNIEXPORT jobjectArray JNICALL Java_com_jni_jernymyjni_GetClassArray (JNIEnv *, jobject); /* * Class: com_jni_jernymyjni * Method: SetClassArray * Signature: ([Lcom/jni/jernymyjni;)I */ JNIEXPORT jint JNICALL Java_com_jni_jernymyjni_SetClassArray (JNIEnv *, jobject, jobjectArray); #ifdef __cplusplus } #endif #endif com_jni_jernymyjni.c的文件内容 + expand sourceview plaincopy to clipboardprint? ·········10········20········30········40········50········60········70········80········90········100·······110·······120·······130·······140·······150 编写Android.mk,内容如下 + expand sourceview plaincopy to clipboardprint? ·········10········20········30········40········50········60········70········80········90········100·······110·······120·······130·······140·······150 在VMware的ubuntu9.04下编译, NDK r4b的路径在../bld/android-ndk-r4-crystax,使用该ndkbuild root@jernymy-desktop:/mnt/hgfs/workspace/AndroidJni# ../bld/android-ndk-r4-crystax/ndk-build Compile thumb : jernymyjni <= /mnt/hgfs/workspace/AndroidJni/jni/com_jni_jernymyjni.c SharedLibrary : libjernymyjni.so Install : libjernymyjni.so => /mnt/hgfs/workspace/AndroidJni/libs/armeabi root@jernymy-desktop:/mnt/hgfs/workspace/AndroidJni# 接下来编写我们的java的测试代码AndroidJni.java,目前为了方便调试,暂且用System.out输出, 可以通过android在界面上摆放一些button,然后把信息显示到button上,就可以看到效果了 现在可以先通过调试的方式,查看debug的信息。 view plaincopy to clipboardprint? ·········10········20········30········40········50········60········70········80········90········100·······110·······120·······130·······140·······150 package com.jni; import android.app.Activity; import android.os.Bundle; public class AndroidJni extends Activity { /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); System.out.println("hello"); jernymyjni cJni = new jernymyjni(); System.out.println("--------jernymy test jernymyjni start--------"); System.out.println("--------display base type test"); System.out.println("--------GetChar('A')--------"); char chTmp = cJni.GetChar('A'); System.out.println(String.valueOf(chTmp)); System.out.println("***************************"); System.out.println("--------SetChar('A')--------"); int nRtn = cJni.SetChar('A'); System.out.println("nRtn:" + String.valueOf(nRtn)); System.out.println("***************************"); System.out.println("--------GetInt(5, 10)--------"); int nSum = cJni.GetInt(5, 10); System.out.println(String.valueOf(nSum)); System.out.println("***************************"); System.out.println("--------SetInt(10)--------"); nRtn = cJni.SetInt(10); System.out.println("nRtn:" + String.valueOf(nRtn)); System.out.println("***************************"); System.out.println("--------GetStr(\"Jernymy Jni GetStr\")--------"); String sStr = cJni.GetStr(); System.out.println(sStr); System.out.println("***************************"); System.out.println("--------GetStr(\"Jernymy Jni PrcsStr\")--------"); sStr = cJni.PrcsStr("Jernymy Jni TestAAA"); System.out.println(sStr); System.out.println("***************************"); System.out.println("--------SetStr(\"Jernymy Jni SetStr\")--------"); nRtn = cJni.SetStr("Java Jni Set"); System.out.println("nRtn:" + String.valueOf(nRtn)); System.out.println("***************************"); System.out.println("------------------------------------------------"); System.out.println("--------display array test"); System.out.println("--------GetCharArray('A')--------"); char[] chAry = cJni.GetCharArray('A'); int nIdx; System.out.println("chAry.length:" + String.valueOf(chAry.length)); for (nIdx = 0; nIdx < chAry.length; nIdx++) { System.out.println(String.valueOf(chAry[nIdx])+" "); } System.out.println("***************************"); System.out.println("--------SetCharArray('A')--------"); nRtn = cJni.SetCharArray(chAry); System.out.println("nRtn:" + String.valueOf(nRtn)); System.out.println("***************************"); System.out.println("--------GetIntArray({1, 2, 3}, {4, 5, 6})--------"); int[] nAddAry1 = {1, 2, 3}; int[] nAddAry2 = {4, 5, 6}; int[] nSumAry = cJni.GetIntArray(nAddAry1, nAddAry2); System.out.println("nSumAry.length:" + String.valueOf(nSumAry.length)); for (nIdx = 0; nIdx < nSumAry.length; nIdx++) { System.out.println(String.valueOf(nSumAry[nIdx])+" "); } System.out.println("***************************"); System.out.println("--------SetIntArray({1, 2, 3}--------"); nRtn = cJni.SetIntArray(nAddAry1); System.out.println("nRtn:" + String.valueOf(nRtn)); System.out.println("***************************"); System.out.println("--------GetStrArray(" + "\"Jernymy Java Jni GetStrArray\")--------"); String[] sStrAry = cJni.GetStrArray(); System.out.println("sStrAry.length:" + String.valueOf(sStrAry.length)); for (nIdx = 0; nIdx < sStrAry.length; nIdx++) { System.out.println(sStrAry[nIdx]+" "); } System.out.println("***************************"); System.out.println("--------PrcsStrArray(" + "\"Jernymy Java Jni PrcsStrArray\")--------"); sStrAry = cJni.PrcsStrArray("Jernymy Android JniTest"); System.out.println("sStrAry.length:" + String.valueOf(sStrAry.length)); for (nIdx = 0; nIdx < sStrAry.length; nIdx++) { System.out.println(sStrAry[nIdx]+" "); } System.out.println("***************************"); System.out.println("--------SetStrArray({\"Jernymy\"," + " \"Java\", \"Jni\", \"SetStrArray\"})--------"); String[] sStrSetAry = {"Jernymy", "Java", "Jni", "SetStrArray"}; nRtn = cJni.SetStrArray(sStrSetAry); System.out.println("nRtn:" + String.valueOf(nRtn)); System.out.println("***************************"); System.out.println("-------------------------------------------------"); System.out.println("--------display class test"); System.out.println("--------GetClass(0)--------"); jernymyjni cComn = cJni.GetClass(0); if (null == cComn) { System.out.println("cComn is null"); } else { System.out.println( "chChar:" + String.valueOf(cComn.chChar) +" nPuId:" + String.valueOf(cComn.nInt) +" sName:" + cComn.sString); } System.out.println("***************************"); System.out.println("--------SetClass({'N', 508, \"Native\"})--------"); jernymyjni cComnSet = new jernymyjni(); cComnSet.chChar = 'N'; cComnSet.nInt = 508; cComnSet.sString = "Native"; nRtn = cJni.SetClass(cComnSet); System.out.println("nRtn:" + String.valueOf(nRtn)); System.out.println("***************************"); System.out.println("--------GetClassArray()--------"); jernymyjni[] sStructAry = cJni.GetClassArray(); System.out.println("sStructAry:" + String.valueOf(sStructAry.length)); for (nIdx = 0; nIdx < sStructAry.length; nIdx++) { System.out.println("----index[" + String.valueOf(nIdx) + "]----"); if (null == sStructAry[nIdx]) { System.out.println("sStructAry is null"); } else { System.out.println("" +" chChar: " + String.valueOf(sStructAry[nIdx].chChar) +", nInt: " + String.valueOf(sStructAry[nIdx].nInt) +", sName: " + sStructAry[nIdx].sString); } } System.out.println("***************************"); System.out.println("--------SetClassArray(Ncomn[])--------"); System.out.println("sStructAry:" + String.valueOf(sStructAry.length)); for (nIdx = 0; nIdx < sStructAry.length; nIdx++) { System.out.println("index[" + String.valueOf(nIdx) +"] chChar:" + String.valueOf(sStructAry[nIdx].chChar) +" nInt:" + String.valueOf(sStructAry[nIdx].nInt) +" sString:" + sStructAry[nIdx].sString); } nRtn = cJni.SetClassArray(sStructAry); System.out.println("nRtn:" + String.valueOf(nRtn)); System.out.println("***************************"); System.out.println("--------Jernymy test jernymyjni end --------"); } } 好了,基本差不多了,因为俺暂时使用的类型已经足够了,至于其他的在继续研究中,如果错误的地方也请您指出,谢谢啦。 jernymy 20110508 jernymy@163.com

下载文档到电脑,查找使用更方便

文档的实际排版效果,会与网站的显示效果略有不同!!

需要 5 金币 [ 分享文档获得金币 ] 1 人已下载

下载文档