android studio下jni传递int,String,数组类型的参数

本文详细介绍了在Android Studio中使用JNI如何传递int、String及数组类型的参数给C层,并回调Java方法。步骤包括在Java中定义native方法、生成头文件、在C中实现方法体。重点讨论了jni.h中定义的基本数据类型,如jint和jstring,并提及数组的处理。虽然不深入探讨C代码,但提供了源码下载链接。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

这篇文章主要讲Java通过jni调用c层时如何传递参数,如何在c的代码中回调Java的方法


上一篇   Android studio下jni的配置和第一个hello word程序  


在上一个例子的基础上继续研究如何通过jni传递参数给c,其实传递参数很简单,先说一下步骤:

1、在Java中定义native的含参的方法

2、使用javah生成头文件

3、在头文件中找到我们含参的方法,并在c中完善它的方法体,返回c最终的处理结果


下面一步一步来详细说明:

public class JNIUtil {
    //直接从c获取一个字符串
   public native String getStringFromC();
    //传递int类型的参数给c,c返回处理结果
    public native int addNum(int x, int y);
    //传递String类型的参数给C 处理一下返回来
    public native String sayFromC(String s);
    //传递int类型的数组给C
    public native int[] arrElementsIncrease(int[] intArray);
}
然后打开Android studio 自带的Terminal,进入app/src/main 目录下,使用如下命令:

javah -d jni -classpath D:\android_studio\sdk\platforms\android-23\android.jar;..\..\build\intermediates\classes\debug com.zhaocd.activity.myjnidemo1.JNIUtil

即可生成头文件com_zhaocd_activity_myjnidemo1_JNIUtil.h  (注意:在JNIUtil中新增了方法后,必须先build -> rebuild preject 一下,不然class文件还是以前的,生成的头文件中也没有新增的方法)

打开头文件,找到我们定义的native的几个方法,然后将它们复制到hello.c的c文件中,完善方法体:

/**
 * 返回两个int类型变量的和
 */
JNIEXPORT jint JNICALL Java_com_zhaocd_activity_myjnidemo1_JNIUtil_addNum
        (JNIEnv * env, jobject obj, jint x, jint y){
    return x+y;
}

为了篇幅的长度,这里只贴出一个方法,因为我们的重点不是c的编写,需要源码的可以在文章末尾下载。


可能大家也注意到了,int对应的jint,string对应的jstring  ,其实这些基本的数据类型都是在jni.h这个文件中定义好的

# include <inttypes.h>      /* C99 */
typedef uint8_t         jboolean;       /* unsigned 8 bits */
typedef int8_t          jbyte;          /* signed 8 bits */
typedef uint16_t        jchar;          /* unsigned 16 bits */
typedef int16_t         jshort;         /* signed 16 bits */
typedef int32_t         jint;           /* signed 32 bits */
typedef int64_t         jlong;          /* signed 64 bits */
typedef float           jfloat;         /* 32-bit IEEE 754 */
typedef double          jdouble;        /* 64-bit IEEE 754 */
#else
typedef unsigned char   jboolean;       /* unsigned 8 bits */
typedef signed char     jbyte;          /* signed 8 bits */
typedef unsigned short  jchar;          /* unsigned 16 bits */
typedef short           jshort;         /* signed 16 bits */
typedef int             jint;           /* signed 32 bits */
typedef long long       jlong;          /* signed 64 bits */
typedef float           jfloat;         /* 32-bit IEEE 754 */
typedef double          jdouble;        /* 64-bit IEEE 754 */
#endif

/* "cardinal indices and sizes" */
一个整形,你定义成int,在生成头文件的时候jni自动会给你转换成jint,知道这个的话就可以无视那个“j”了,ndk会把Java的数据类型和c的数据类型进行转换。

除了基本的数据类型,肯定还有数组了

typedef void*           jobject;
typedef jobject         jclass;
typedef jobject         jstring;
typedef jobject         jarray;
typedef jarray          jobjectArray;
typedef jarray          jbooleanArray;
typedef jarray          jbyteArray;
typedef jarray          jcharArray;
typedef jarray          jshortArray;
typedef jarray          jintArray;
typedef jarray          jlongArray;
typedef jarray          jfloatArray;
typedef jarray          jdoubleArray;
typedef jobject         jthrowable;
typedef jobject         jweak;
可以看到不管是什么类型的数组,都是先转换成jarray -> jobject -> void*   。 void*是一种特别的指针,说它特别是因为它不能判断出数据的类型,或者说根据这个类型不能判断出指向对象的长度。


由于我们开发项目时,一般很少自己去写c层的代码,而是使用一些开源的现成的类库或者由c++工程师写,所以这里就不对c做深入的研究了~~~~


源码下载


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值