JNI - Слушатель в C++/Java - возможно ли создавать экземпляры объектов Java в C++ и использовать их в качестве параметров
Можно ли использовать следующее с JNI?
public NativeClass {
static {
System.loadLibrary("dll");
}
public static native void addListener(Listener listener);
}
public interface Listener {
public void eventOccurred(Info info);
}
public Info {
private final String s1;
private final String s2;
public Info(String s1, String s2);
// ... getters for use in Java
}
Это возможно
- зарегистрировать
Listener
объект на dll (не должно быть проблем, насколько я узнал) - создавать экземпляр
Info
объект в коде c/ C++ и использовать его в качестве параметра для вызоваListener.eventOccured(Info...)
?
Или какой хороший способ реализовать слушателя, который получает некоторую информацию из DLL?
В моем случае - у нас есть dll, которая делает какую-то работу. Мы называем это DLL из Java. Теперь мы хотим подключить слушателя к dll, чтобы он давал нам информацию о прогрессе во время работы. Приведенный выше пример - это часть слушателя, которую я не знаю, возможно ли это в связи с вызовом конструктора для конструктора Java из c/ C++.
Подсказка, где найти часть документации, которая описывает ответ, была бы хороша - я не мог найти информацию, которая ответила на мой вопрос.
Небольшой фрагмент кода, описывающий часть c/ C++, был бы обледенением на торте:)
1 ответ
Короткий ответ - да, вы можете хранить, создавать и передавать объекты Java на собственном уровне через JNI.
В документации jni вы найдете функции, которые сделают это за вас. http://docs.oracle.com/javase/7/docs/technotes/guides/jni/spec/functions.html
Вы также будете использовать javap -s
а также javah
помочь найти ваши сигнатуры java-метода для использования в jni и сделать ваши jni-заголовки. См. http://docs.oracle.com/javase/7/docs/technotes/tools/windows/javap.html & http://docs.oracle.com/javase/7/docs/technotes/tools/windows/javah.html
Вот пример того, что вы будете делать. Я не проверял это, так что просто используйте его как справочник для написания своего. Примечание: помните о нотациях пакетов (я не предполагал, что пакет) и об исключениях. Исключения могут происходить при любом вызове JNI (env->...
), поэтому проверьте документацию о том, как бороться с исключениями (ExceptionCheck
, ExceptionDescribe
, ExceptionClear
).
JavaVM * savedVM = NULL;
JNIEXPORT void JNICALL Java_NativeClass_addListener(JNIEnv *env, jobject obj_instance, jobject listener_instance)
{
env->GetJavaVM( &savedVM );
//save listener_instance for use later
saved_listener_instance = listener_instance;
}
void doSomething()
{
//Get current thread JNIEnv
JNIEnv * ENV;
int stat = savedVM->GetEnv((void **)&ENV, JNI_VERSION_1_6);
if (stat == JNI_EDETACHED) //We are on a different thread, attach
savedVM->AttachCurrentThread((void **) &ENV, NULL);
if( ENV == NULL )
return; //Cant attach to java, bail
//Get the Listener class reference
jclass listenerClassRef = ENV->GetObjectClass( saved_listener_instance );
//Use Listener class reference to load the eventOccurred method
jmethodID listenerEventOccured = ENV->GetMethodID( listenerClassRef, "eventOccurred", "(LInfo;)V" );
//Get Info class reference
jclass infoClsRef = ENV->FindClass( "Info" );
//Create Info class
jobject info_instance = ENV->NewObject( infoClsRef, ..... );//For you to fill in with your arguments
//invoke listener eventOccurred
ENV->CallVoidMethod( saved_listener_instance, listenerEventOccured, info_instance );
//Cleanup
ENV->DeleteLocalRef( info_instance );
}
Это хороший пример: https://github.com/NickZt/MyJNACallbackTest Этот же код подробно описан здесь: https://www.hackster.io/user2657268124/a-beginner-s-guide-to-implement-jni-callbacks-in-android-cd8226