前面一篇讲了C++字符串三种方式,下面就给出这三种方式的例子
通过C++代码将Java控制台输入的字符串倒序输出到Java控制台:
Java代码都是一样的
public class TestNative {
public native void sayHello(); // C++本地代码实现
public String message=null;
public static void main(String[] args) throws IOException {
System.loadLibrary("NativeCode");// 加载动态链接库,不能加 .dll
BufferedReader reader=new BufferedReader(new InputStreamReader(System.in));
String str=reader.readLine();
TestNative test = new TestNative();
test.message=str;
test.sayHello();
System.out.println("Java Output: "+test.message);
}
}
1、GetStringChars
#include "com_fomagic_TestNative.h"
#include <iostream>
using namespace std;
//对 com_fomagic_TestNative.h 中声明的方法定义
JNIEXPORT void JNICALL Java_com_fomagic_TestNative_sayHello (JNIEnv *env, jobject obj)
{
jclass clazz_TestNative = env->GetObjectClass(obj);
jfieldID fid_msg= env->GetFieldID(clazz_TestNative,"message","Ljava/lang/String;");//注意分号,老吃亏
jstring j_msg=(jstring) env->GetObjectField(obj,fid_msg);
const jchar* jstr=env->GetStringChars(j_msg,NULL);//UTF-16编码的宽字符串(jchar*)
wstring wstr(((const wchar_t*)jstr));
env->ReleaseStringChars(j_msg,jstr);//释放
reverse(wstr.begin(),wstr.end());//进行字符串的倒序
jstring j_new_str=env->NewString((const jchar*)wstr.c_str(),(jint)wstr.size());//创建新字符串对象
env->SetObjectField(obj,fid_msg,j_new_str); //对创建的字符串进行赋值
}
注:
wstring是宽char,Unicode编码,一个字符占两个字节大小
string是窄char,ASCII编码,一个字符占一个字节大小
string/wstring了,它们两分别对应着char和wchar_t。
2、GetStringCritical
效果和第一种是一样的,只是将调用方法和释放方法改变
JNIEXPORT void JNICALL Java_com_fomagic_TestNative_sayHello (JNIEnv *env, jobject obj)
{
jclass clazz_TestNative = env->GetObjectClass(obj);
jfieldID fid_msg= env->GetFieldID(clazz_TestNative,"message","Ljava/lang/String;");
jstring j_msg=(jstring) env->GetObjectField(obj,fid_msg);
const jchar* jstr=env->GetStringCritical(j_msg,NULL);
wstring wstr(((const wchar_t*)jstr));
env->ReleaseStringCritical(j_msg,jstr);
reverse(wstr.begin(),wstr.end());
jstring j_new_str=env->NewString((const jchar*)wstr.c_str(),(jint)wstr.size());
env->SetObjectField(obj,fid_msg,j_new_str);
}
3、GetStringRegion
JNIEXPORT void JNICALL Java_com_fomagic_TestNative_sayHello (JNIEnv *env, jobject obj)
{
jclass clazz_TestNative = env->GetObjectClass(obj);
jfieldID fid_msg= env->GetFieldID(clazz_TestNative,"message","Ljava/lang/String;");
jstring j_msg=(jstring) env->GetObjectField(obj,fid_msg);
jsize len=env->GetStringLength(j_msg);
jchar* jstr=new jchar[len+1]; //这里需要注意,C++中字符串以'\0'结尾
jstr[len]=L'\0'; //宽字符串
env->GetStringRegion(j_msg,0,len,jstr);
wstring wstr(((const wchar_t*)jstr));
delete [] jstr; //释放<span style="color: #555555;">分配出来存储字符串的空间</span>
reverse(wstr.begin(),wstr.end());
jstring j_new_str=env->NewString((const jchar*)wstr.c_str(),(jint)wstr.size());
env->SetObjectField(obj,fid_msg,j_new_str);
}