jni返回结构体数组

转自: https://blog.csdn.net/zhangchao012/article/details/8546896

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代码
  <code class="language-html">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();  
 }  
 </code>  

这个是要返回的结构体(在java中好像叫类 嘿嘿)

package com.example.jnitest2;

 public class  mx2Data{
    public  String name;
    public  int   index;
 }

这里还是放jni源码

<code class="language-java">#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;  
 }  
 </code>  
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值