Я пытаюсь присвоить поле byte[] в структуре Java непосредственно в C++ с помощью метода env->SetObjectField(), но на этом этапе всегда происходит сбой.
В моем коде Java у меня есть такая структура:
public class DataStruct {
public boolean myBoolean;
public String myString;
public byte[] myArray;
/*some setter and getter methods*/
}
Из встроенной части моего кода JNI у меня есть это:
jclass arrayClass = env->FindClass("java/util/ArrayList");
jmethodID arrayMethodId = env->GetMethodID(arrayClass, "", "()V");
jobject objArr = env->NewObject(arrayClass, arrayMethodId);
jmethodID arrayMethodIdAdd = env->GetMethodID(arrayClass, "add", "(Ljava/lang/Object;)Z");
while (continueLoop) {
jclass objClass = env->FindClass("path/to/my/DataStruct");
jmethodID objMethodId = env->GetMethodID(objClass, "", "()V");
jobject dataObject = env->NewObject(objClass, objMethodId);
jfieldID myBooleanField = env->GetFieldID(objClass, "myBoolean", "Z");
jfieldID myStringField = env->GetFieldID(objClass, "myString", "Ljava/lang/String;");
jfieldID myArrayField = env->GetFieldID(objClass, "myArray", "[B");
jboolean bool = getSomeBoolean();
env->SetBooleanField(dataObject, myBooleanField, bool);
std::string str = getSomeString();
env->SetObjectField(dataObject, myStringField, env->NewStringUTF(str.c_str()));
jbyteArray arr = getSomeArrays();
env->SetObjectField(dataObject, myArrayField, arr);
env->CallBooleanMethod(objArr, arrayMethodIdAdd, dataObject);
}
return objArr;
Как видите, я пытаюсь создать ArrayList непосредственно на C++ и вернуть его в Java. Большая часть кода C++ работает: он создает объект DataStruct, получает идентификаторы логических полей, String и byte[], устанавливает логические поля и String, но в тот момент, когда он достигает метода env->SetObjectField() для поля byte[], я получаю следующую ошибку:
java_vm_ext.cc:594] JNI DETECTED ERROR IN APPLICATION: JNI ERROR (app bug): jobject is an invalid JNI transition frame reference or invalid reference: 0x7db6c32000 (use of invalid jobject)
java_vm_ext.cc:594] in call to SetObjectField
Если я не пытаюсь присвоить это поле массива, код работает так, как ожидалось.
Как сказано в документации на рисунке 3-1, jbyteArray (например, jstring) является проектом, поэтому я использовал env->SetObjectField(), но похоже, что jbyteArray здесь не принимается.
Я пропустил что-нибудь?
Я думал о преобразовании этого массива байтов в строку и передаче ему структуры Java как есть, но я не совсем уверен, что это лучший способ.
РЕДАКТИРОВАТЬ:
Это моя настоящая функция getSomeArrays();: