cmo*_*opm 6 java-native-interface android android-ndk
我的应用需要使用jni.逻辑看起来像:
void myJniFunc(JNIEnv *env, jclass clazz, jobjectArray items) {
int count = 10;
struct MyObj *myObjArray = (struct MyObj*)malloc(sizeof(struct MyObj) * count);
for (i = 0; i < count; i++) {
jobject obj = (*env)->GetObjectArrayElement(env, items, i);
jfieldID fieldId = ...;
jstring jstr = (*env)->GetObjectField(env, obj, fieldId);
myObjArray[i].name = (*env)->GetStringUTFChars(env, jstr);
(*env)->DeleteLocalRef(env, obj);
// Location A
}
// some code which will use myObjArray
process(count, myObjectArray);
// Location B
}
Run Code Online (Sandbox Code Playgroud)
通过JNI doc,GetStringUTFChars返回的数组应该使用
(*env)->ReleaseStringUTFChars(env, jstr, myObjArray[i].name);
(*env)->ReleaseLocalRef(env, jstr);
Run Code Online (Sandbox Code Playgroud)
我的问题是:如果我想正确释放jstring,我该怎么办?
由于你的循环正在创建本地引用(GetObjectField),你需要在循环中释放它(DeleteLocalRef),否则你将遇到本地引用的限制.您必须在两次调用之间完全处理Java字符串.
由于您希望保留字符串的字节以便在循环外使用,因此需要复制字节,因为在释放字符串引用之前必须释放JVM的固定(或临时副本)(GetStringUTFChars)(ReleaseStringUTFChars).
所以循环中字符串的顺序必须是:
GetObjectField
GetStringUTFChars
ReleaseStringUTFChars
DeleteLocalRef
注意:GetStringUTFChars
您将获得指向Java String的修改后的UTF-8编码的指针.这里有两点:
GetStringUTFLength
获取修改的UTF-8编码中的字节数 - 不计算任何0终止符.(各种JNI实现和本书都同意该数组以0结尾.)如果您想使用终结器制作自己的副本,请务必为终结器添加空间.如果您更喜欢使用UTF-16编码,请使用GetStringChars
和GetStringLength
.在这种情况下,阵列绝对不会终止; 它使用内部计数和字符串字节而不进行任何转换.
或者,如果您想更改字符集,比如真正的"UTF-8","ASCII","CP437"或"Windows-1252"或您的代码可以处理的其他内容,请使用String.getBytes
重载或Charset
类.Charset
如果要控制如何处理目标字符集中不支持的字符,请使用该类.
归档时间: |
|
查看次数: |
4559 次 |
最近记录: |