Vik*_*yan 10 java-native-interface callback
在这里,我在JAVA中创建了一个类,我有一个函数(回调),我必须从C文件中调用它.
class DSMInitializeClassParameter {
/**
* Callback function for DSM Initialize.
*/
public void DSMInitializeCallback( ) {
// Write Message To Logs.
System.out.println( "Dsm Initialize Callback called." );
}
}
Run Code Online (Sandbox Code Playgroud)
为此,我创建了必须调用的本机方法.
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);
}
Run Code Online (Sandbox Code Playgroud)
在C文件中我有以下内容:
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 );
}
Run Code Online (Sandbox Code Playgroud)
你怎么看我要打电话(*env)->CallVoidMethod(env, classObject, mid);从dsmInitializeCall功能,但我怎么能叫,如果我没有env,classObject而且mid我尝试用静态,但它不能正常工作.
Mic*_*zek 24
缓存实例并继续使用它通常是不安全的JNIEnv*,因为它根据当前活动的线程而变化.您可以保存一个JavaVM*永不改变的实例.在本机初始化函数中,调用GetJavaVM并传递JavaVM指针的地址:
static JavaVM *jvm;
JNIEXPORT void JNICALL Java_SomeClass_init(JNIEnv *env, jclass) {
int status = (*env)->GetJavaVM(env, &jvm);
if(status != 0) {
// Fail!
}
}
Run Code Online (Sandbox Code Playgroud)
现在您可以使用它JavaVM*来获取当前JNIEnv*的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);
}
Run Code Online (Sandbox Code Playgroud)
小智 8
确保您将JavaVM作为第一个业务顺序的引用的另一种方法是添加JNI_OnLoad方法并缓存引用.这将在加载共享库时调用.
防爆.
static JavaVM* cachedJVM;
JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *jvm, void *reserved)
{
cachedJVM = jvm;
// ... Any other initialization code.
}
Run Code Online (Sandbox Code Playgroud)
一旦获得了JavaVM指针的引用,就可以使用Michael Mrozek在上面的帖子中描述的方法.
| 归档时间: |
|
| 查看次数: |
9989 次 |
| 最近记录: |