JNIEnv源码分析 (对比c、c++)

思考这个问题,在jni中,c语言与c++对方法的调用为啥不一样

1、C语言JNIEnv分析

在C语言中我们对jni是这样处理的

#include <jni.h>
#include <string>

JNIEXPORT jstring

jstring Java_com_hs_androidcmakedemo_MainActivity_GetHell
        (JNIEnv *env, jobject job) {
    return (*env)->NewStringUTF(env, "string from cplusplus");
}

点开JNIEnv,我们看到jni.h头文件源代码#138行。

typedef const struct JNINativeInterface* JNIEnv;
typedef const struct JNIInvokeInterface* JavaVM;

这里我们看到C语言中的JNIEnv是个指针类型,接着JNIEnv定义了*env,说明env是个二级指针。

那么取值(*env),就是解引用,变成一级指针,如果想访问结构体的方法则需要加个箭头,如下

(*env)->NewStringUTF(env, "string from cplusplus");

又因为C语言中没有this指针,所以这里C语言中所有的函数第一个参数都是JNIEnv,相当于this对象传入调用者

jobject     (*CallObjectMethod)(JNIEnv*, jobject, jmethodID, ...);
jobject     (*CallObjectMethodV)(JNIEnv*, jobject, jmethodID, va_list);
jobject     (*CallObjectMethodA)(JNIEnv*, jobject, jmethodID, jvalue*);
jboolean    (*CallBooleanMethod)(JNIEnv*, jobject, jmethodID, ...);

2、C++语言JNIEnv分析

在C++语言中我们对jni是这样处理的

JNIEXPORT jstring JNICALL
Java_com_hs_androidcmakedemo_MainActivity_GetHell(JNIEnv *env, jobject thiz) {
    std::string hello = "Hello from C++";
    return env->NewStringUTF(hello.c_str());
}

同样点开JNIEnv,我们看到jni.h头文件源代码#138行。

typedef _JNIEnv JNIEnv;
typedef _JavaVM JavaVM;

接着打开_JNIEnv,我们发现它是个结构体struct

image-20220127202810611

这里我们看到C++语言中的JNIEnv是个结构体的别名,接着JNIEnv定义了*env,说明env是个一级指针。

一级指针使用箭头函数访问成员,如下

env->NewStringUTF(hello.c_str());

又因为C++中有this指针(当前对象),所以这里不需要额外传env

3、为何设计上C与C++的JNIEnv不同

背景:首先在C语言中没有别名的概念,在C++语言中才开始有别名。而别名用在函数参数接收时特别有用。

分析:在JNIEnv传入到Java_com_hs_androidcmakedemo_MainActivity_GetHell方法中没办法使用别名去接收,这里就必须用指针接收,所以导致了C语言这里出现了二级指针。所以说这里不是不这样做,而是这样做不了。

typedef _JNIEnv JNIEnv;
typedef _JavaVM JavaVM;
jstring Java_com_hs_androidcmakedemo_MainActivity_GetHell
        (JNIEnv *env, jobject job) {
    return (*env)->NewStringUTF(env, "string from cplusplus");
}

因此开发jni、ndk,使用C++要比C要清爽点

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

流星雨在线

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值