JNI - JAVA 数据类型转换



基本数据类型转换

在 Java 中传递的参数类型是 int,而在 JNI 中就成了 jint,这就涉及到 Java 到 JNI 的数据类型转换。

Java 类型Native 类型字节长度
booleanjboolean8位
bytejbyte8位
charjchar16位
shortjshort16位
intjnit32位
longjlong64位
floatjfloat32位
doublejdouble64位

引用数据类型转换

除了基本数据类型之外,引用数据类型也有着一一对应。

Java 类型Native 类型
objectsjobject
java.lang.Classjclass
java.lang.Stringjstring
Object[]jobjectArray
boolean[]jbooleanArray
byte[]jbyteArray
char[]jcharArray
short[]jshortArray
int[]jintArray
long[]jlongArray
float[]jfloatArray
double[]jdoubleArray
java.lang.Throwablejthrowable

除了 Java 中基本数据类型的数组、Class、String 和 Throwable 外,其余所有 Java 对象的数据类型在 JNI 中都用 jobject 表示。

String 字符串操作

对于基本数据类型的操作,比如 boolean、int、float 等都大同小异,无非是在原来的数据类型前面加了一个 j来表示 JNI 数据类型。
而对于 String 类型,必须要使用合适的 JNI 函数来将 jstring 转变成 C/C++ 字符串。
对于下面的 Native 方法,传入一个字符串,并要求返回一个字符串。

external fun stringFromJNI(): String

layout1Binding.tv1.setOnLongClickListener {
       val str = strFromJNI("我是Java向C传递的参数")
       layout1Binding.tv1.text = str
        true

        }

生成的对应的 C++ 代码如下:

extern "C"
JNIEXPORT jstring JNICALL
Java_com_znzy_myapplication_MainActivity_strFromJNI(JNIEnv *env, jobject thiz, jstring string) {
    // 生成jstring
    jstring returnValue = env->NewStringUTF("Hello Best");
    // 把jstring类型的字符串转换为C风格的字符串,会额外申请内存
    const char *str = env->GetStringUTFChars(string,0);
    // 做检查判断
    if (str == NULL){
        return NULL;
    }
    // 实际操作
    printf("%s",str);
    LOGE("%s",str);
    //释放申请的内存
    env->ReleaseStringUTFChars(string,str);
    return returnValue;
}

通过Java调用验证发现日志正常输出,页面正常显示

在这里插入图片描述

Java 层的字符串到了 JNI 就成了 jstring 类型的,但 jstring 指向的是 JVM 内部的一个字符串,它不是 C 风格的字符串 char*,所以不能像使用 C 风格字符串一样来使用 jstring 。

JNI 支持将 jstring 转换成 UTF 编码和 Unicode 编码两种。因为 Java 默认使用 Unicode 编码,而 C/C++ 默认使用 UTF 编码。
将 jstring 转换成 UTF 编码的字符串

  • GetStringUTFChars(jstring string, jboolean* isCopy)

其中,jstring 类型参数就是我们需要转换的字符串,而 isCopy 参数的值为 JNI_TRUE 或者 JNI_FALSE ,代表是否返回 JVM 源字符串的一份拷贝。如果为JNI_TRUE 则返回拷贝,并且要为产生的字符串拷贝分配内存空间;如果为JNI_FALSE就直接返回了JVM 源字符串的指针,意味着可以通过指针修改源字符串的内容,但这就违反了 Java 中字符串不能修改的规定,在实际开发中,直接填 NULL就好了。

当调用完GetStringUTFChars 方法时别忘了做完全检查。因为 JVM 需要为产生的新字符串分配内存空间,如果分配失败就会返回 NULL,并且会抛出 OutOfMemoryError 异常,所以要对 GetStringUTFChars 结果进行判断。

当使用完 UTF 编码的字符串时,还不能忘了释放所申请的内存空间。调用 ReleaseStringUTFChars 方法进行释放。

除了将 jstring 转换为 C 风格字符串,JNI 还提供了将 C 风格字符串转换为 jstring 类型。

通过 NewStringUTF函数可以将 UTF 编码的 C 风格字符串转换为 jstring 类型,通过NewString 函数可以将 Unicode 编码的 C 风格字符串转换为 jstring 类型。这个 jstring 类型会自动转换成 Java 支持的 Unicode 编码格式。

除了 jstring 和 C 风格字符串的相互转换之外,JNI 还提供了其他的函数。

String 字符串函数操作总结

JNI 函数描述
GetStringChars / ReleaseStringChars获得或释放一个指向 Unicode 编码的字符串的指针(指 C/C++ 字符串)
GetStringUTFChars / ReleaseStringUTFChars获得或释放一个指向 UTF-8 编码的字符串的指针(指 C/C++ 字符串)
GetStringLength返回 Unicode 编码的字符串的长度
getStringUTFLength返回 UTF-8 编码的字符串的长度
NewString将 Unicode 编码的 C/C++ 字符串转换为 Java 字符串
NewStringUTF将 UTF-8 编码的 C/C++ 字符串转换为 Java 字符串
GetStringCritical / ReleaseStringCritical获得或释放一个指向字符串内容的指针(指 Java 字符串)
GetStringRegion获取或者设置 Unicode 编码的字符串的指定范围的内容
GetStringUTFRegion获取或者设置 UTF-8 编码的字符串的指定范围的内容
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值