Quantcast
Channel: CSDN博客移动开发推荐文章
Viewing all articles
Browse latest Browse all 5930

[JNI]开发之旅(8)传递参数给JNI函数

$
0
0

本节将介绍在JNI编程中如何传递参数和返回值。

首先要强调的是,native方法不但可以传递Java的基本类型做参数,还可以传递更复杂的类型,比如String,数组,甚至自定义的类。jni.h中定义了很多接口供我们操作。

其实在前面章节的例子中,我们已经使用到很多java传递参数给jni的例子,只是没有重点介绍,接下来会对传递几种基本类型参数,string,数组,java自定义对象这些参数介绍。

1. 基本类型的传递

实例1:传递int类型给JNI函数

java代码:


    public native int intMethod(int n);

JNI实现代码:


//传递int参数
extern "C"
jint Java_com_honjane_ndkdemo_JNIUtils_intMethod( JNIEnv* env, jobject jobj,jint num){

    return num*num;
}

注意:num没有经过转换,直接使用的。对的8中基本数据类型传递都可以直接使用,不需要再转换,而string,数组,对象就不能直接使用了,需要把jni数据结构转换成c,c++的数据结构才能操作。

结果:
传递num = 4;

I/main----intMethod: 16


实例2:传递boolean类型给JNI函数

java层:

    public native boolean booleanMethod(boolean bool);

JNI实现:


//传递布尔类型
extern "C"
jboolean Java_com_honjane_ndkdemo_JNIUtils_booleanMethod(JNIEnv* env,jobject jobj,jboolean flag){

    return !flag;
}

结果:
flag == true

I/main----booleanMethod: false

这里就介绍2个基本数据类型传参,其他几个类型,可以自行去实现。

2. String参数的传递

Java的String和C++的string是不能对等起来的,不能直接使用,需要通过一些函数转换。

实例3:传递String给JNI函数,把参数拼接到jni字符上,然后给java层使用

java代码:

    public native String stringMethod(String text);

JNI实现:

//传递string类型
extern "C"
jstring Java_com_honjane_ndkdemo_JNIUtils_stringMethod(JNIEnv* env,jobject jobj,jstring jstr){
    //将jstring类型转换成c++识别的char类型
    const char * str = env->GetStringUTFChars(jstr,0);
    char c[120] = "lily ";
    //调用c++拼接字符函数
    strcat(c,str);
    //释放
    env->ReleaseStringUTFChars(jstr,str);
    return env->NewStringUTF(c);
}

我们看到与实例1,2两个不一样,拿到jstring后,通过GetStringUTFChars把java层传过来的参数转换成char指针,然后才能操作。

结果:
text:hello

I/main----stringMethod: lily hello

3. 数组参数的传递

实例4:传递一个int数组给jni,然后实现数字元素求和

java代码:

    public native int intArrayMethod(int[] intArray);

JNI实现:


extern "C"
jint Java_com_honjane_ndkdemo_JNIUtils_intArrayMethod(JNIEnv* env,jobject jobj,jintArray jarr){
     jint len=0,sum=0;
     //获得数组长度
     len = env->GetArrayLength(jarr);
     //转换数组为int指针
     jint* body = env->GetIntArrayElements(jarr,0);
     //由于一些版本不兼容,i不定义在for循环中
     jint i=0;
     for(;i<len;i++){
        sum+=body[i];
     }
    return sum;
}

结果:
arr = {3,5,6,12,46,33};

I/main----intArrayMethod: 105

4. 自定义java对象参数的传递

实例5:传递复杂对象person,再jni函数中新构造一个person传回java层输出

定义Person

public class Person {
    private String name;
    private int age;


    public Person() {
    }

    public Person(int age, String name) {
        this.age = age;
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }

    @Override
    public String toString() {
        return "Person :{ name: "+name+",age: "+age+"}";
    }


}

java层native函数

    public native Person objectMethod(Person person);

JNI实现:


//传递person自定义对象给jni函数
extern "C"
jobject  Java_com_honjane_ndkdemo_JNIUtils_objectMethod(JNIEnv* env,jobject jobj,jobject jperson){
    jclass jcls = env->GetObjectClass(jperson);
//    jclass jcls =  env->FindClass("com/honjane/ndkdemo/model/Person"); //或反射得Person类引用

    if(jcls == NULL){
        return env->NewStringUTF("not find class");
    }
    //得到person对象的构造函数Person(int,string)
    jmethodID constrocMID = env->GetMethodID(jcls,"<init>","(ILjava/lang/String;)V");
    if(constrocMID == NULL){
        return env->NewStringUTF("not find constroc method");
    }

    jstring str = env->NewStringUTF("honjane");
     //构造一个对象,调用该类的构造函数,并且传递参数
    jobject new_ojb = env->NewObject(jcls,constrocMID,21,str); 

 return new_ojb;
}

输出结果:

I/main----objectMethod: Person :{ name:honjane ,age:21}
作者:tsdfk1455 发表于2017/1/1 0:34:14 原文链接
阅读:28 评论:0 查看评论

Viewing all articles
Browse latest Browse all 5930

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>