如何创建静态 JNI 环境指针? [英] How to create static JNI Environment Pointer?
问题描述
在这里,我在 JAVA 中创建了一个类,其中有我必须从 C 文件调用的函数(回调).
Here I create a class in JAVA in which I have function (callback) which I must call from C file.
class DSMInitializeClassParameter {
/**
* Callback function for DSM Initialize.
*/
public void DSMInitializeCallback( ) {
// Write Message To Logs.
System.out.println( "Dsm Initialize Callback called." );
}
}
为此,我创建了必须调用的本地方法.
For that I have created native method which must be called.
public class DsmLibraryTest extends Activity {
// Some code ....
// Create a DSMInitializeClassParameter class object.
DSMInitializeClassParameter object = new DSMInitializeClassParameter();
// Call native method with given object.
nativeMethod( object );
// Some code ....
// Implementation of native method.
public native int nativeMethod(DSMInitializeClassParameter classObject);
}
在 C 文件中,我有以下内容:
In C file I have following:
dsmResult_t dsmInitializeCall( dsmResult_t status, void * pUserData, dsmEvent_t * hEvent ) {
(*env)->CallVoidMethod(env, classObject, mid);
}
JNIEXPORT jint JNICALL Java_com_Dsm_Test_DsmLibraryTest_nativeMethod(JNIEnv* env, jobject obj, jobject classObject) {
// This function loads a locally-defined class. It searches the directories and zip
// files specified by the CLASSPATH environment variable for the class with the specified name.
jclass cls = (*env)->FindClass( env, "com/Dsm/Test/DSMInitializeClassParameter" );
// Get java Method.
jmethodID mid = (*env)->GetMethodID(env, cls, "DSMInitializeCallback", "()V");
// If no method was found return -1;
if( mid == NULL ) {
return -1;
}
// Call DSM Initialize Callback Function and return value.
return dsmInitialize( dsmInitializeCall, NULL );
}
你怎么看我想从 dsmInitializeCall
函数调用 (*env)->CallVoidMethod(env, classObject, mid);
,但是我怎么能调用如果我没有 env
、classObject
和 mid
我尝试使用静态但它不起作用.
how you can see I want to call (*env)->CallVoidMethod(env, classObject, mid);
from dsmInitializeCall
function, but how I can call it if I have no env
, classObject
and mid
I try with statics but it not work.
推荐答案
一般是 不安全 缓存 JNIEnv*
实例并继续使用它,因为它根据当前活动的线程而变化.您可以保存一个 JavaVM*
实例,它永远不会改变.在本机初始化函数中,调用 GetJavaVM
并将 JavaVM
指针的地址传递给它:
It's generally unsafe to cache a JNIEnv*
instance and keep using it, as it varies depending on the currently active thread. You can save a JavaVM*
instance, which will never change. In a native initializer function, call GetJavaVM
and pass it the address of a JavaVM
pointer:
static JavaVM *jvm;
JNIEXPORT void JNICALL Java_SomeClass_init(JNIEnv *env, jclass) {
int status = (*env)->GetJavaVM(env, &jvm);
if(status != 0) {
// Fail!
}
}
现在您可以使用 JavaVM*
获取当前的 JNIEnv*
和 AttachCurrentThread
:
Now you can use that JavaVM*
to get the current JNIEnv*
with AttachCurrentThread
:
dsmResult_t dsmInitializeCall( dsmResult_t status, void * pUserData, dsmEvent_t * hEvent ) {
JNIEnv *env;
(*jvm)->AttachCurrentThread(jvm, (void **)&env, NULL);
(*env)->CallVoidMethod(env, classObject, mid);
}
这篇关于如何创建静态 JNI 环境指针?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!