Я только начинаю работать с JNI, и у меня есть следующая проблема.
У меня есть библиотека C++ с простым классом. У меня есть три метода JNI, вызываемые из проекта Java Android, которые создают указанный класс, вызывают метод для созданного класса и уничтожают его соответственно. Я сохраняю глобальную ссылку на этот объект, чтобы он был доступен для меня в двух других методах JNI.
Я подозреваю, что не могу этого сделать. Когда я запускаю приложение, я получаю ошибку времени выполнения (используется устаревшая ссылка), и я подозреваю, что это связано с тем, что глобальная ссылка недействительна при последующих вызовах других методов JNI.
Это единственный способ добиться того, чего я хочу (сохранить объект при нескольких вызовах JNI), фактически передать указатель на созданный класс обратно в Java, сохранить его там, а затем передать обратно в JNI. функции? Если да, то все в порядке, я хочу убедиться, что не могу сделать это с глобальной ссылкой, и я не просто что-то упустил.
Я прочитал документацию и главы о глобальных/локальных ссылках в JNI, но похоже, что это применимо только к классам Java, а не к моим собственным, нативным классам C++, или я ошибаюсь.
Вот код, если мое описание непонятно (резюмируя, мне интересно, будет ли вообще работать этот механизм сохранения объектов):
Java:
package com.test.ndktest;
import android.app.Activity;
import android.os.Bundle;
import android.app.AlertDialog;
public class NDKTestActivity extends Activity {
static {
System.loadLibrary("ndkDTP");
}
private native void initializeTestClass();
private native void destroyTestClass();
private native String invokeNativeFunction();
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
initializeTestClass();
String hello = invokeNativeFunction();
destroyTestClass();
new AlertDialog.Builder(this).setMessage(hello).show();
}
}
Заголовок JNI:
extern "C" {
jstring Java_com_test_ndktest_NDKTestActivity_initializeTestClass(JNIEnv* env, jobject javaThis);
jstring Java_com_test_ndktest_NDKTestActivity_destroyTestClass(JNIEnv* env, jobject javaThis);
jstring Java_com_test_ndktest_NDKTestActivity_invokeNativeFunction(JNIEnv* env, jobject javaThis);
};
JNI тело:
#include <string.h>
#include <jni.h>
#include <ndkDTP.h> //JNI header
#include <TestClass.h> //C++ header
TestClass *m_globalTestClass;
void Java_com_test_ndktest_NDKTestActivity_initializeTestClass(JNIEnv* env, jobject javaThis) {
m_globalTestClass = new TestClass(env);
}
void Java_com_test_ndktest_NDKTestActivity_destroyTestClass(JNIEnv* env, jobject javaThis) {
delete m_globalTestClass;
m_globalTestClass = NULL;
}
jstring Java_com_test_ndktest_NDKTestActivity_invokeNativeFunction(JNIEnv* env, jobject javaThis) {
jstring testJS = m_globalTestClass->getString();
return testJS;
}
Заголовок C++:
class TestClass
{
public:
jstring m_testString;
JNIEnv *m_env;
TestClass(JNIEnv *env);
jstring getString();
};
Тело C++:
#include <jni.h>
#include <string.h>
#include <TestClass.h>
TestClass::TestClass(JNIEnv *env){
m_env = env;
m_testString = m_env->NewStringUTF("TestClass: Test string!");
}
jstring TestClass::getString(){
return m_testString;
}
Спасибо