jni入门(二)

引言

即上一篇JNI系列之入门Hello JNI C(一)简单介绍后,这篇将详细讲解C中的所有代码。


  • 理解C中native函数实现的意思 我们来看生成出来的native函数声明
/*
 * Class:     com_jerry_jnitest_JniTest
 * Method:    getStringFromC
 * Signature: ()Ljava/lang/String;
 */
JNIEXPORT jstring JNICALL Java_com_jerry_jnitest_JniTest_getStringFromC
  (JNIEnv *, jclass);
复制代码
  1. Java_com_jerry_jnitest_JniTest_getStringFromC这一长串是函数名,它是有规律的: Java_native方法在java类中的包名全称_native的方法名 原来java里native方法:
public native static String getStringFromC();
复制代码
  1. 再来看返回值 jstring,对应的是java中native方法的返回值String,通过VS右击它转到定义,会发现它就是一个_jobject结构体指针变量jobject的别名:Paste_Image.png
  2. 参数JNIEnv *,它在java的native方法里没有对应的参数,这个是JNI接口函数特有的,包括后面的jclass或者jobject是必须有的两个参数。 JNIEnv *是个啥玩意呢,通过VS转到定义:Paste_Image.png 有两个地方都声明了: 一个是C++的,一个是C的。 C中是结构体指针struct JNINativeInterface_ *的一个别名,那就说明JNIEnv *就是一个二级指针类型。 C++中:Paste_Image.png 图中可以看到JNIEnv是JNIEnv_的一个别名,而JNIEnv_是个结构体,里面JNINativeInterface_ *function作为它的一个成员变量,图中可以看到C++对function的函数封装了一层,参数传了this,也就是当前functions这个结构体指针其实就是上文C中JNIEnv这个JNINativeInterface_ *结构体指针的别名。那意思就很明白了,在c++中native函数的JNIEnv *就是一级指针。 至于C中为什么要用二级指针,应该是结构体中的那些函数指针的具体实现都需要用到JNINativeInterface_ *这个结构体指针吧。(这段话比较拗口,会比较难理解,可以多看看思考思考) native函数中,第二个参数jclass,看看它的定义:Paste_Image.png 其实它的意思就是相对于java的Class类型,因为我们在Java中写的native方法是 static修饰的所以直接是类类型来访问应用这个native方法。 如果java中改成:
public native String getStringOfC(String input);
复制代码

那就变成了:

JNIEXPORT jstring JNICALL Java_com_jerry_jnitest_JniTest_getStringOfC
  (JNIEnv *env, jobject jobj, jstring jstr){

    }
复制代码

这里面jobject标示这个native方法是调用它的对象,第三个参数jstring就是java方法中String input这个参数。 从上文可以看出,jxxxx的都会对应Java中的一种数据类型。

下面是Java的数据类型与JNI的数据类型的映射关系:

Java数据类型Jni数据类型C数据类型
基础数据类型  
voidvoidvoid
booleanjbooleanunsigned char
bytejbytesigned char
charjcharchar
shortjshortshort
intjintint
longjlong__int64(long long)
floatjfloatfloat
doublejdoubledouble
引用数据类型  
Stringjstring (jobject的别名)struct _jobject*
Objectjobjectstruct _jobject*
基本数据类型的数组  
blooean[]jbooleanArray
1. jbooleanArray是jarray的别名
2. jarray又是jobject的别名
struct _jobject *
byte[]jbyteArray
1. jbyteArray是jarray的别名
2. jarray又是jobject的别名
struct _jobject *
char[]jcharArray
1. jcharArray是jarray的别名
2. jarray又是jobject的别名
struct _jobject *
short[]jshortArray
1. jshortArray是jarray的别名
2. jarray又是jobject的别名
struct _jobject *
int[]jintArray
1. jintArray是jarray的别名
2. jarray又是jobject的别名
struct _jobject *
long[]jlongArray
1. jlongArray是jarray的别名
2. jarray又是jobject的别名
struct _jobject *
float[]jfloatArray
1. jfloatArray是jarray的别名
2. jarray又是jobject的别名
struct _jobject *
double[]jdoubleArray
1. jdoubleArray是jarray的别名
2. jarray又是jobject的别名
struct _jobject *
引用数据类型数组  
Object[]jobjectArray
1. jobjectArray是jarray的别名
2. jarray又是jobject的别名


作者:JerryloveEmily
链接:https://juejin.im/post/5b5b17d5f265da0f9e58aa0d
来源:掘金
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值