字符串的使用¶
前面我们知道如何使用基本数据类型,本文我们来看如何将字符串传入和传出本地(native)方法。
我们先来看一个返回String的例子,分别看kotlin代码与cpp代码。
class Jerry {
companion object {
init {
System.loadLibrary("fisher-pole")
}
}
external fun name(): String?
}
extern "C"
JNIEXPORT jstring JNICALL
Java_com_rustfisher_fishpole_worker_Jerry_name(JNIEnv *env, jobject thiz) {
std::string jerry = "Jerry";
return env->NewStringUTF(jerry.c_str());
}
在c++代码中,我们调用了env->NewStringUTF();
方法来获得jstring。
调用方法的写法是:env->
再加上具体的方法。
NewStringUTF
函数可以用来构造一个新的jstring,而读取现有jstring对象的内容,需要使用GetStringUTFChars
函数。
该函数返回指向描述字符串的“改良UTF-8”字符的 const jbyte* 指针。
注意,具体的虚拟机可以为其内部的字符串表示自由选择编码机制。
所以,你可以得到实际的Java字符串的字符指针。
因为Java字符串是不可变的,所以慎重处理const就显得非常重要,不要试图将数据写到该字符数组中。另一方面,如果虚拟机使用UTF-16或UTF-32字符作为其内部字符串的表示,那么该函数会分配一个新的内存块来存储等价的“改良UTF-8”编码字符。
虚拟机必须知道你何时使用完字符串,这样它就能进行垃圾回收(垃圾回收器是在一个独立线程中运行的,它能够中断本地方法的执行)。基于这个原因,你必须调用ReleaseStringUTFChars
函数。
另外,可以通过调用GetStringRegion
或GetStringUTFRegion
方法来提供你自己的缓存,以存放字符串的字符。
最后GetStringUTFLength
函数返回字符串的“改良UTF-8”编码所需的字符个数。
倒序字符串的例子¶
有了上面的知识后,我们来尝试把输入的字符串倒序输入。
首先准备native方法,在kotlin代码增加reverseString
方法
class Jerry {
companion object {
init {
System.loadLibrary("fisher-pole")
}
}
external fun reverseString(input: String): String?
}
编写C++实现,在jerry.cpp中增加代码
extern "C"
JNIEXPORT jstring JNICALL
Java_com_rustfisher_fishpole_worker_Jerry_reverseString(JNIEnv *env, jobject thiz, jstring input) {
const char *inputPtr = env->GetStringUTFChars(input, NULL);
int len1 = env->GetStringLength(input);
int len2 = strlen(inputPtr);
char *out = new char[len1 + 1]{}; // 这里需要多一位
for (int i = 0; i < len1; i++) {
out[i] = inputPtr[len1 - i - 1];
}
jstring res = env->NewStringUTF(out);
delete[] out;
env->ReleaseStringChars(input, reinterpret_cast<const jchar *>(inputPtr));
return res;
}
len1
和len2
其实是一样的。两种方法获取传入字符串的长度。
首先拿到传入的jstring的内容,用env->GetStringUTFChars
方法。获得一个const char指针。
然后新分配一个char数组,拿来存放倒序后的内容。
env->NewStringUTF
新建一个jstring,就是我们要的结果。
最后回收资源,并返回结果。
实际项目中,并不会这么做,这只是个示例。
代码在这 https://gitee.com/rustfisher/AndroidTutorial
本站说明
一起在知识的海洋里呛水吧。广告内容与本站无关。如果喜欢本站内容,欢迎投喂作者,谢谢支持服务器。如有疑问和建议,欢迎在下方评论~