其它的字符串函数
1)jstring NewString(const jchar* str, jsize len);
2)jstring NewStringUTF(const char* str);
3)jsize GetStringLength(jstring str);
4)jsize GetStringUTFLength(jstring str);
如何在C/C++代码中创建Java对象?
java code:
public class MainTest {
static {
System.loadLibrary("jnitest1");
}
public String message = null;
public native void callCppFunction();
public static void main(String[] args) {
MainTest mt = new MainTest();
mt.message = "xxx";
mt.callCppFunction();
System.out.println(mt.message);
}
}
c code:
jfieldID fid_msg = env->GetFieldID(env->GetObjectClass(obj), "message", "Ljava/lang/String;");
jstring j_msg = (jstring)env->GetObjectField(obj, fid_msg);
const jchar jstr = env->GetStringChars(j_msg, NULL);
__android_log(jstr); //这句好像不正确,需要改下。。。
env->ReleaseStringChars(j_msg, jstr);
5)GetStringCritical
为了增加直接传回指向java字符串的指针的可能性(而不是拷贝),JDK1.2出来了新的函数GetStringCritical/ReleaseStringCritical。
const jchar* GetStringCritical(jstring str, jboolean* copied);
void ReleaseStringCritical(jstring jstr, const jchar* str);
在GetStringCritical/ReleaseStringCritical之间是一个关键区,在这关键区之中绝对不能呼叫JNI的其它函数和会造成当前线程中断或是会让当前线程等待的任何本地代码,否则将造成关键区代码执行期间垃圾回收期停止工作,任何处罚垃圾回收期的代码也会暂停,其它的触发垃圾回收器的线程不能前进直到当前线程结束而激活垃圾回收器。
在关键区中千万不要出现中断操作,或是在JVM中分配任何新对象,否则会造成JVM死锁。
虽说这个函数会增加直接传回指向java字符串的指针的可能性,不过还是会根据情况传回拷贝过的字符串。
const jchar jstr = env->GetStringCritical(j_msg, NULL);
env->ReleaseStringCritical(j_msg, jstr);
6)GetStringRegion, GetStringUTFRegion
1.java1.2出来的函数,函数把java字符串的内容直接拷贝到C/C++的字符数组中,在呼叫这个函数之前必须有一个C/C++分配出来的字符串,然后传入到这个函数中进行字符串的拷贝。
2.由于C/C++中分配内存开销相对小,而且java中的String内容拷贝的开销可以忽略,更好的一点事此函数不分配内存,不会抛出OOM异常。
//拷贝java字符串并以UTF-8编码传入buffer
GetStringUTFRegion(jstring str, jsize start, jsize len, char* buffer);
// 拷贝Java字符串并以UTF-16编码传入buffer
GetStringRegion(jstring str, jsize start, jsize len, jchar * buffer);