Я пытаюсь интегрировать некоторый код JNI в свое приложение, которое получает данные от веб-службы и анализирует их на уровне JNI. Я пытаюсь вызвать метод, определенный на уровне Java, передав некоторые аргументы, полученные от веб-службы. Ниже приведен поток функций и методов:
Переменные, определенные для jclass и jmethodID:
static jclass userInfo = NULL ;
static jmethodID create_user_info = NULL ;
Структура, определенная на уровне c для хранения значений
struct User_Info {
long userId; // 1
std::string firstName; // 2
std::string lastName; // 3
bool follow; // 4
};
У этой функции есть проблема. Эта функция вызывается после получения данных от веб-сервиса, их разбора и создания структуры User_Info.
static jobject createJavaObject(JNIEnv *env, const User_Info& info) {
if(!userInfo){
userInfo = (jclass)env->NewGlobalRef(env->FindClass("com/model/UserInfo"));
assert(userInfo != NULL);
create_user_info = env->GetStaticMethodID(userInfo, "createUserInfo", "("
"I" // userId // 1
"Ljava/lang/String;" // firstName // 2
"Ljava/lang/String;" // lastName // 3
"Z" // follow // 4
")Lcom/model/UserInfo;");
assert(create_user_info != 0);
}
jstring firstName = cast<jstring>(env, info.first_name); // cast function just converts string to jstring
assert(firstName != NULL);
jstring lastName = cast<jstring>(env, info.last_name); // cast function just converts string to jstring
assert(lastName != NULL);
// ISSUE IS WITH FOLLOWING CALL
jobject res = env->CallStaticObjectMethod(userInfo, create_user_info,
info.userId, // 1
firstName, // 2
lastName, // 3
info.follow // 4
);
env->DeleteLocalRef(firstName);
env->DeleteLocalRef(lastName);
return res;
}
// cast function:
jstring cast<jstring, char const *>()(JNIEnv *env, char const *s) {
if (!s) return 0;
jbyteArray bytes = env->NewByteArray(strlen(s));
env->SetByteArrayRegion(bytes, 0, strlen(s), (jbyte*)s);
jmethodID midStringCtor = env->GetMethodID(clsString, "<init>", "([BLjava/lang/String;)V");
jstring ret = (jstring)env->NewObject(clsString, midStringCtor, bytes, encoding);
env->DeleteLocalRef(bytes);
return ret;
}
Java-метод:
@Native
private static UserInfo createUserInfo(
int userId, // 1
String firstname, // 2
String lastname, // 3
boolean follow // 4
) {
UserInfo info = new UserInfo();
info.userId = userId;
info.firstname = firstname;
info.lastname = lastname;
info.follow = follow;
return info;
}
Проблема в том, что когда я запускаю код, я получаю следующую ошибку:
ОШИБКА JNI (ошибка приложения): ожидается jboolean (0/1), но получено значение 1048605 в качестве аргумента 4 для com.model.UserInfo com.model.UserInfo.createUserInfo(int, java.lang.String, java.lang.String, логическое значение)
Когда я меняю порядок аргументов в методе java и функциях jni и сохраняю логическое значение «follow» сразу после int «userId», проблема не возникает.
Мой вопрос:
Требует ли JNI упорядочения аргументов на основе их типов, например. параметр int перед long/boolean или примитивные параметры перед объектами и т. д.
Если да, есть ли какие-либо ссылки/документы, которые предлагают это, если нет, то почему мой код работает после изменения порядка аргументов?
struct __attribute__ ((__packed__)) User_Info { blah blah };
- person Michael   schedule 23.08.2016info.follow ? JNI_TRUE : JNI_FALSE
? - person user2543253   schedule 23.08.2016userId
кjint
? - person user2543253   schedule 23.08.2016