脚本宝典收集整理的这篇文章主要介绍了NDK开发 - JNI基本数据和字符串处理,脚本宝典觉得挺不错的,现在分享给大家,也给大家做个参考。
第一篇搭建环境,第二篇了解开发流程,第三篇扯了一些理论,这一篇是时候展现真正的技术了,主要是写一些 JNI 的基本类型数据处理以及字符串的处理,字符串是最经常涉及的数据类型。
JNI 开发中主要涉及基本数据的处理,引用数据的处理,数组的处理。String 作为比较常用的引用数据类型 JNI 也提供了特有的的方法处理。在处理应用类型的时候需要注意内存的释放,不然很可能造成内存溢出。C/C++ 中的内存不能依靠 Java 的 GC 线程管理,下一篇会介绍 JNI 的引用类型。
涉及的代码地址:https://github.com/gnaix92/as-ndk
C 和 C++ 函数实现的比较
唯一的差异在于用来访问 JNI 函数的方法。在 C 中,JNI 函数调用由(*env)->
作前缀,目的是为了取出函数指针所引用的值。在 C++ 中,JNIEnv 类拥有处理函数指针查找的内联成员函数。下面将说明这个细微的差异,其中,这两行代码访问同一函数,但每种语言都有各自的语法。
C 语法: jsize len = (*env)->GetArrayLength(env,array);
C++ 语法: jsize len =env->GetArrayLength(array);
下面涉及的代码都是用 C++ 开发的。所以看到网上用 C 开发的 JNI 也不需要奇怪。
@H_126_26@处理基本类型
JNI 中的基本类型和 Java 中的基本类型是一一对应的,这个在上一篇提到过。下面是 JNI 的基本类型定义:
tyPEdef unsigned char jboolean;
typedef unsigned short jchar;
typedef short jshort;
typedef float jfloat;
typedef double jdouble;
typedef int jint;
#ifdef _LP64 /* 64-bIT solaris */
typedef long jlong;
#else
typedef long long jlong;
#endif
typedef signed char jbyte;
基本类型很容易理解,就是对 C/C++ 中的基本类型用 typedef 重新定义了一个新的名字,在 JNI 中可以直接访问。
JNIexport jint JNicalL Java_com_example_gnaix_ndk_NativeMethod_getInt
(JNIEnv *env, jclass object, jint num)
{
int len;
char buf[1024];
__System_PRoperty_get("ro.serialno", buf);
LOGD("serialno : %s", buf);
len = strlen(buf);
return num + len;
}
处理字符串
JNI 把 Java 中所有对象当作一个 C 指针传递到本地方法中,这个指针指向 JVM 中的内部数据结构,而内部的数据结构在内存中的存储方式是不可见得。只能从 JNIEnv 指针指向的函数表中选择合适的 JNI 函数来操作 JVM 中的数据结构。
String 在 Java 是一个引用类型,所以在本地代码中只能通过GetStringUTfchars 这样的 JNI 函数来访问字符串的内容。
先看一个例子: