我需要通过JNI将字符串列表从Java传递给C. 我的Java程序传递一个List参数,C程序接受一个列表。
以下是我尝试的代码。
JNIEXPORT jobject JNICALL Java_jni_CallJNIfunction(JNIEnv *env,
jobjectArray jParameters){
list<const char*> cParameters;
jsize stringCount = env->GetArrayLength(jParameters);
for (int i=0; i<stringCount; i++) {
jstring arrElement = (jstring) (env->GetObjectArrayElement(jParameters, i));
const char* nativeElement = env->GetStringUTFChars( arrElement, NULL);
cParameters.push_back(nativeElement);
env->ReleaseStringUTFChars(arrElement, nativeElement);
}
CallCfunction(cParameters);
}
但是我的JVM在GetStringUTFChars()行崩溃了。 这个程序有什么问题?
答案 0 :(得分:2)
你这样做:
const char* nativeElement = env->GetStringUTFChars( arrElement, NULL);
cParameters.push_back( nativeElement );
env->ReleaseStringUTFChars(arrElement, nativeElement);
您将存储的字符串释放到列表中,因此列表中包含许多错误的指针!
您必须将字符串复制到长时间分配的空间中,您可以选择std :: string,char * + malloc或use-it-and-forget-it方法。
第三种解决方案的说明:
for( int i = 0; i < stringCount; ++i )
{
jstring arrElement = (jstring) (env->GetObjectArrayElement(jParameters, i));
const char* nativeElement = env->GetStringUTFChars( arrElement, NULL);
CallCfunction( nativeElement ); // modified to process an item not a list<
env->ReleaseStringUTFChars(arrElement, nativeElement);
}
答案 1 :(得分:0)
以下代码将使用Set<String>
并将其转换为std::vector<std::string>
,但我不会这样做,您最好使用{{1将集合转换为数组在toArray
上的方法,您可以使用原始代码。
Set
但除非你有一个巨大的JNIEXPORT jobject JNICALL Java_jni_CallJNIfunction(
JNIEnv *env,
jclass,
jobject setObj) {
jmethodID iteratorID = env->GetMethodID(env->FindClass("java/util/Set"), "iterator", "()Ljava/util/Iterator;");
jclass iterator = env->FindClass("java/util/Iterator");
jmethodID hasNextID = env->GetMethodID(iterator, "hasNext", "()Z");
jmethodID nextID = env->GetMethodID(iterator, "next", "()Ljava/lang/Object;");
std::vector<std::string> strSet;
jobject iteratorObj = env->CallObjectMethod(setObj, iteratorID);
while (env->CallBooleanMethod(iteratorObj, hasNextID) == JNI_TRUE) {
jstring current = (jstring)env->CallObjectMethod(iteratorObj, nextID);
const char* str = env->GetStringUTFChars(current, NULL);
strSet.push_back(str);
env->ReleaseStringUTFChars(current, str);
}
}
复制到数组太慢或占用太多内存,否则我会转换为数组。
答案 2 :(得分:0)
简单的C函数的第一个答案是:
char **GetStringsfromJniStringArray(JNIEnv *env, jobjectArray stringArray) {
size_t stringCount = (size_t)(*env)->GetArrayLength(env, stringArray);
char **Strings=calloc(stringCount, sizeof(char*));
int i = 0;
for(i = 0; i < (int)stringCount; ++i )
{
jstring jniString = (jstring) (*env)->GetObjectArrayElement(env, stringArray, i);
const char *TempString = (*env)->GetStringUTFChars(env, jniString, NULL);
Strings[i] = calloc(strlen(TempString)+1, sizeof(char));
strcpy(Strings[i], TempString);
(*env)->ReleaseStringUTFChars(env, jniString, TempString);
}
return Strings;
}