简而言之,答案是肯定的,您可以通过 JNI 在本机层中保存、实例化和传递 Java 对象。
在 jni 文档中,您将找到可以为您执行此操作的函数。http://docs.oracle.com/javase/7/docs/technotes/guides/jni/spec/functions.html http://docs.oracle.com/javase/7/docs/technotes/guides/jni/spec/functions.html
您还将使用javap -s
and javah
帮助查找在 jni 中使用的 java 方法签名并制作 jni 标头。看http://docs.oracle.com/javase/7/docs/technotes/tools/windows/javap.html http://docs.oracle.com/javase/7/docs/technotes/tools/windows/javap.html & http://docs.oracle.com/javase/7/docs/technotes/tools/windows/javah.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 );
}