现在的位置: 首页 > 综合 > 正文

jni返回结构体数组

2017年12月28日 ⁄ 综合 ⁄ 共 5568字 ⁄ 字号 评论关闭

    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;
 }
 


抱歉!评论已关闭.