나는 JNI로 막 시작했으며 다음과 같은 문제가 있습니다.JNI는 객체에 대한 전역 참조를 유지하고 다른 JNI 메소드로 객체에 액세스합니다. 여러 JNI 호출에 걸쳐 C++ 객체 유지하기
나는 간단한 클래스를 가진 C++ 라이브러리를 가지고있다. 자바 안드로이드 프로젝트에서 3 개의 JNI 메쏘드를 호출했다. 클래스는 클래스를 선언하고 인스턴스화 된 클래스에 메소드를 호출하고 파괴한다. 이 객체에 대한 전역 참조를 유지하므로 다른 두 JNI 메소드에서 사용할 수 있습니다.
나는 이것을 할 수 없다고 생각합니다. 응용 프로그램을 실행할 때 런타임 오류가 발생했습니다 (참조가 오래됨). 다른 JNI 메서드에 대한 이후 호출에서 전역 참조가 유효하지 않기 때문에 이것이 의심스러운 것 같습니다.
내가 원하는 것 (객체가 여러 JNI 호출에 걸쳐 살아있게)을 얻는 유일한 방법은 실제로 인스턴스화 된 클래스에 대한 포인터를 Java로 다시 전달하고 거기에 보관 한 다음 다시 전달하는 것입니다. JNI는 기능합니까? 그렇다면 괜찮습니다. 전 세계적으로 참조 할 수 없도록하고 싶습니다. 뭔가 빠져있는 것이 아닙니다.
JNI의 전역/로컬 참조에 대한 설명서와 장을 읽었지만 Java 클래스에만 적용되고 내 고유 C++ 클래스에는 적용되지 않거나 잘못되었습니다.
자바 : 내 설명이 명확하지 않은 경우 다음
는 (객체를 지속이 메커니즘이 전혀 작동하는지 궁금하고, 요약) 코드입니다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;
}
감사
그게 다야! 나는 그 문제가 다른 곳에 있다고 확신했다. 어쨌든, 큰 도움이됩니다. 고마워요! – cierech