jni返回结构体数组.这个卡了我两天.好郁闷.从网上找了好多的办法都不成功. 可能是人品问题,呵呵呵
好在现在搞定了.把源码贴出来让大家也看看,希望能帮到那些和我人品不好的人嘿嘿..
其实回想起来.挺简单的. 返回结构体数组有如下步骤.
/*
* 返回一个结构体数组步骤
* 1.通过FindClass找到要返回的android中定义的class.
* 2.通过NewObjectArray创建一个要返回的结构体数组.
* 3.通过GetMethodID得到你要返回的class的默认构造方法
* 4.通过GetFieldID得到定义的class里面所有的成员
* 5.通过NewObject创建一个对应的class对象
* 6.通过SetObjectField为5创建的class对象赋值(如果字段为int,那么就用SetIntField这个方法)
* 7.通过SetObjectArrayElement把创建的class对象放到创建的objectArray里面去
* 8.返回这个objectArray对象.
* 9.完成. 就这么简单.
* */
是不是简单啊. 嘿嘿嘿嘿.
好.现在看是放源码.
android 代码.
这个代码是activity 代码
package com.example.jnitest2; import android.os.Bundle; import android.app.Activity; import android.util.Log; import android.view.Menu; public class MainActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); MX2 changeJni = new MX2(); changeJni.displayParms("Hello World!", 100, true); int ret = changeJni.add(12, 20); Log.e("logZ", "相加结果为:"+ret); boolean[] blList = new boolean[] { true, false, true }; changeJni.setArray(blList); String[] strList = changeJni.getStringArray(); for (int i = 0; i < strList.length; i++) { Log.e("logZ", "第"+i+"string为:"+ strList[i]); } //返回一个结构 mx2Data data = changeJni.getStruct(); Log.e("logZ", "名称为"+data.name+"序列为"+data.index); //返回一个结构数组 mx2Data[] dataList = changeJni.getStructArray(); for (int i = 0; i < dataList.length; i++) { Log.e("logZ", "第"+i+"个:"+"名称为"+data.name+"序列为"+data.index); } } @Override public boolean onCreateOptionsMenu(Menu menu) { // Inflate the menu; this adds items to the action bar if it is present. getMenuInflater().inflate(R.menu.activity_main, menu); return true; } }
这个是调用jni代码
package com.example.jnitest2; public class MX2 { static { System.loadLibrary("myjni"); } public native void displayParms(String showText, int i, boolean bl); // 返回两个int相加 public native int add(int a, int b); // 输入一个数组 public native void setArray(boolean[] blList); // 返回一个字符串数组 public native String[] getStringArray(); // 返回一个结构 public native mx2Data getStruct(); // 返回一个结构数组 public native mx2Data[] getStructArray(); }这个是要返回的结构体(在java中好像叫类 嘿嘿)package com.example.jnitest2; public class mx2Data{ public String name; public int index; }这里还是放jni源码#include "jni.h" #include <stdio.h> #include <math.h> #include <stdio.h> #include "stdlib.h" #include "string.h" /* 作用为: 传入的参数为:string, int, boolean 返回是处理后的s. */ JNIEXPORT void JNICALL jni_displayParms(JNIEnv *env, jobject obj, jstring s, jint i, jboolean b) { const char* szStr = (env)->GetStringUTFChars(s, 0 ); printf( "String = [%s]\n", szStr ); printf( "int = %d\n", i ); printf( "boolean = %s\n", (b==JNI_TRUE ? "true" : "false") ); (env)->ReleaseStringUTFChars(s, szStr ); } /* 返回两个整数相加. */ JNIEXPORT jint JNICALL jni_add(JNIEnv *env, jobject, jint a, jint b) { int rtn = (int) (a + b); return (jint) rtn; } /* 处理一个bool数组. */ JNIEXPORT void JNICALL jni_setArray(JNIEnv *env, jobject, jbooleanArray ba) { jboolean* pba = (env)->GetBooleanArrayElements(ba, 0 ); jsize len = (env)->GetArrayLength(ba); int i=0; for( i=0; i < len; i+=2 ) { pba[i] = JNI_FALSE; printf( "boolean = %s\n", (pba[i]==JNI_TRUE ? "true" : "false") ); } (env)->ReleaseBooleanArrayElements(ba, pba, 0 ); } /* 返回一个string数组. */ JNIEXPORT jobjectArray JNICALL jni_getStringArray(JNIEnv *env, jobject) { jstring str; jobjectArray args = 0; jsize len = 5; const char* sa[] = { "Hello,", "world!", "mx2", "is", "good" }; int i = 0; args = (env)->NewObjectArray(len, (env)->FindClass("java/lang/String"), 0); for (i = 0; i < len; i++) { str = (env)->NewStringUTF(sa[i]); (env)->SetObjectArrayElement(args, i, str); } return args; } /* 返回一个java object对象. */ JNIEXPORT jobject JNICALL jni_getStruct(JNIEnv *env, jobject obj) { //获取Java中的mx2Data类 jclass objectClass = (env)->FindClass("com/example/jnitest2/mx2Data"); //得到这个类的构造方法id. //得到类的默认构造方法的id.都这样写. jmethodID consID = (env)->GetMethodID(objectClass, "<init>", "()V"); //获取类中每一个变量的定义 //name jfieldID str = (env)->GetFieldID(objectClass, "name", "Ljava/lang/String;"); //index jfieldID idex = (env)->GetFieldID(objectClass, "index", "I"); //创建一个jobject对象. jobject myReturn = (env)->NewObject(objectClass, consID); //给每一个实例的变量赋值 (env)->SetObjectField(myReturn, str, (env)->NewStringUTF("mei xiang 2")); (env)->SetIntField(myReturn, idex, 10); return myReturn; } /* 返回一个jobject数组. 这里放回的是 mx2Data类的数组. */ JNIEXPORT jobjectArray JNICALL jni_getStructArray(JNIEnv *env, jobject _obj) { jobjectArray MXArray = NULL; // jobjectArray 为指针类型 jclass clsMX = NULL; // jclass 为指针类型 jobject obj; jint len = 5; //设置这个数组的长度. //知道要返回的class. clsMX = env->FindClass("com/example/jnitest2/mx2Data"); //创建一个MXAray的数组对象. MXArray = env->NewObjectArray(len, clsMX, NULL); //获取类中每一个变量的定义 //name jfieldID str = (env)->GetFieldID(clsMX, "name", "Ljava/lang/String;"); //index jfieldID idex = (env)->GetFieldID(clsMX, "index", "I"); //得到这个类的构造方法id. //得到类的默认构造方法的id.都这样写. jmethodID consID = (env)->GetMethodID(clsMX, "<init>", "()V"); for (jint i = 0; i < len; i++) { obj = env->NewObject(clsMX, consID); env->SetObjectField(obj, str, env->NewStringUTF("mx is mingxiang")); env->SetIntField(obj, idex, (jint) i); env->SetObjectArrayElement(MXArray, i, obj); } return MXArray; } /* 创建调用的方法数组. { "displayParms", "(Ljava/lang/String;IZ)V", (void*)jni_displayParms }, java里面调用的方法 , (java调用时传入的参数类型)返回的类型 , 对应的jni里面的函数. */ static JNINativeMethod const gMethods[] = { { "displayParms", "(Ljava/lang/String;IZ)V", (void*)jni_displayParms }, { "add", "(II)I", (void*)jni_add }, { "setArray", "([Z)V",(void*)jni_setArray }, { "getStringArray", "()[Ljava/lang/String;",(void*) jni_getStringArray }, { "getStruct", "()Lcom/example/jnitest2/mx2Data;",(void*) jni_getStruct }, { "getStructArray", "()[Lcom/example/jnitest2/mx2Data;",(void*) jni_getStructArray }, }; /* jni_Onload方法.照着写就行了. */ jint JNI_OnLoad(JavaVM *jvm, void *reserved) { JNIEnv* env = NULL; if (jvm->GetEnv((void**) &env, JNI_VERSION_1_4) != JNI_OK) { return -1; } jclass clazz = (env)->FindClass("com/example/jnitest2/MX2"); //这里是唯一的要注意的. 这里的mx2是在java中引用jni类的类名. (env)->RegisterNatives(clazz, gMethods, sizeof(gMethods) / sizeof(gMethods[0])); return JNI_VERSION_1_4; } void JNI_OnUnload(JavaVM *jvm, void *reserved) { return; }