Tôi chỉ mới bắt đầu với JNI và tôi có một vấn đề sau đây.JNI giữ một tham chiếu toàn cục đến một đối tượng, truy cập nó với các phương thức JNI khác. Giữ một đối tượng C++ còn tồn tại trên nhiều cuộc gọi JNI
Tôi có thư viện C++ có lớp đơn giản. Tôi có ba phương pháp JNI được gọi là từ dự án Java Android, instatiate nói lớp, gọi một phương thức trên lớp instantiated, và tiêu diệt nó, tương ứng. Tôi giữ một tham chiếu toàn cầu đối tượng này, vì vậy nó sẽ có sẵn cho tôi trong hai phương pháp JNI khác.
Tôi nghi ngờ rằng tôi không thể thực hiện việc này. Khi tôi chạy ứng dụng, tôi nhận được một lỗi thời gian chạy (sử dụng tài liệu tham khảo cũ), và tôi nghi ngờ rằng điều này là do việc giới thiệu toàn cầu không hợp lệ trong các cuộc gọi tiếp theo đến các phương thức JNI khác.
Là cách duy nhất để đạt được những gì tôi muốn (có đối tượng sống qua nhiều cuộc gọi JNI), để thực sự truyền lại con trỏ đến lớp được khởi tạo trở lại Java, giữ nó ở đó và sau đó chuyển nó trở lại JNI hoạt động? Nếu vậy, điều đó tốt, tôi muốn chắc chắn rằng tôi không thể làm điều đó với một tham chiếu toàn cầu, và tôi không chỉ thiếu một cái gì đó.
Tôi đã đọc tài liệu và các chương về tham chiếu toàn cầu/cục bộ trong JNI, nhưng có vẻ như chỉ áp dụng cho các lớp Java chứ không phải các lớp C++ gốc của riêng tôi hoặc tôi sai.
Đây là mã nếu mô tả của tôi là không rõ ràng (tóm tắt, tôi tự hỏi nếu cơ chế này của sự bền bỉ đối tượng sẽ làm việc tại tất 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();
}
}
Tiêu đề 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 body:
#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++ tiêu đề:
class TestClass
{
public:
jstring m_testString;
JNIEnv *m_env;
TestClass(JNIEnv *env);
jstring getString();
};
C++ cơ thể:
#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;
}
Cảm ơn
Đúng rồi! Tôi chắc chắn vấn đề là ở nơi khác. Dù sao, giúp đỡ rất nhiều. Cảm ơn rất nhiều! – cierech