常用的字符串传递有2种方式 使用例程进行测试
示例一 GetStringUTFRegion【推荐使用】
#include <stdio.h>
// demo.cpp
jstring jni_debug_string(JNIEnv *jenv, jobject thiz,
jstring str){
LOGI("[%s]START#1\n", __FUNCTION__);
char outputbuf[128];
char inputbuf[128];
int len = jenv->GetStringLength(str);
LOGI("[%s]GetStringLength:%d", __FUNCTION__, len);
jenv->GetStringUTFRegion(str, 0, len, inputbuf);
sprintf(outputbuf, "thanks %s", inputbuf);
LOGI("[%s]inputbuf:%s", __FUNCTION__, inputbuf);
LOGI("[%s]outputbuf:%s", __FUNCTION__, outputbuf);
return jenv->NewStringUTF(outputbuf);
}
示例二 GetStringUTFChars
#include <stdio.h>
// demo.cpp
jstring jni_debug_string(JNIEnv *jenv, jobject thiz,
jstring str){
LOGI("[%s]START#2\n", __FUNCTION__);
const char* str_input;
jboolean isCopy = false;
char outputbuf[128];
//char inputbuf[128];
str_input = jenv->GetStringUTFChars(str, &isCopy);
LOGI("[%s]str_input:%s", __FUNCTION__, str_input);
sprintf(outputbuf, "thanks %s", str_input);
jenv->ReleaseStringUTFChars(str, str_input);
LOGI("[%s]outputbuf:%s", __FUNCTION__, outputbuf);
return jenv->NewStringUTF(outputbuf);
}
例程分析
由2个实际示例可以看出
GetStringUTFRegion 需要预先定义一个空间 inputbuf 来存放从java中传递过来的字符串,
虽然是需要增加了一个变量(即空间)进行存放,但是变量由自己控制。
GetStringUTFChars 是接口内部分配内存的方式来获取一个空间来存放java过来的字符串,
也是相当于增加了一个空间,只是把申请内存空间的操作封装到接口里面实现,
所以需要 ReleaseStringUTFChars 来对接口内部申请的空间进行释放。
就两种方式比较,可以看作第二种方式就是把第一种方式的调用稍微封装一下进行使用,
把本应该由用户自己定义空间在存放变量的操作封装到接口内部,省去用户自己定义的操作。
这里更推荐是方式一,由用户自己定义的空间更为直观控制。
NewStringUTF 是由env向java层进行调用,
则相关的内存管理也是有java管理,相当于在java层 new String[len]; 不涉及到c++的内存申请。
安卓上层调用接口
findViewById(R.id.button1).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
on_set_string();
}
});
// public native String jni_debug_string(String str_in);
private void on_set_string() {
String data;
data = String.format("%s", "Android");
data = jniclass.jni_debug_string(data);
Toast.makeText(MainActivity.this, data, Toast.LENGTH_SHORT).show();
}
上层需要使用 String.format 进行文字的格式化,否则会提示报错
直接赋值时 data = “Android”;
提示错误 input is not valid Modified UTF-8: illegal start byte 0xf4
普通格式化 data = String.format(“Android”);
提示错误 input is not valid Modified UTF-8: illegal start byte 0xff
如果调用 jni_debug_string 之前使用过Log输出,结果也是正常不报错状态
Log.i(“MainActivity”, “data:” + data);
更推荐使用例程中的 String.format("%s", “Android”);
所以jni直接接收String数据类型时,必须进行格式化,
不然无法确认字符串的完整性导致错误。