GetStringUTFChars和GetStringUTFRegion的使用示例

本文介绍了在JNI编程中两种常用的字符串传递方法:GetStringUTFRegion和GetStringUTFChars,并对比了它们的区别及适用场景。推荐使用GetStringUTFRegion,因为它允许开发者直接控制缓冲区,避免了额外的内存管理操作。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

常用的字符串传递有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数据类型时,必须进行格式化,
不然无法确认字符串的完整性导致错误。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值