Chap16:JNI的c代码中,另外一个线程获取 JNIEnv

32 篇文章 0 订阅

JNI 中,JNIEnv*指针变量只对当前线程有效。如果是其他的线程,需要先获得 JVM*指针,然后再获得当前线程的JNIEnv*指针。部分示例代码为:

/** Invoker.cpp, Invoker.java */

#include <jni.h>

#include <stdio.h>

#include "Invoker.h"

#include "invoker_include.h"

JavaVM *   jvm;

JNIEnv *   static_env;

 

jobject *  jObject; //线程间公用,必须使用 global reference

jclass    c;         //必须使用 global reference

jmethodID m;   //必须使用 global reference

 

/*****************************

* Class:     Invoker

* Method:    register

* Signature: ()V

*****************************/

JNIEXPORT void JNICALLJava_Invoker_register (JNIEnv *env, jobject arg)

{

jObject = arg;

 

// printf("object: %x, %x. \n", &arg,&jObject);

printf("[main] Invoker registered.\n");

 

jclass bgpClass =(*env)->GetObjectClass(env, arg);

jmethodID methodId =(*env)->GetMethodID(env, bgpClass, "invoke", "()V");

printf("[main] -class: %d, method: %d\n", bgpClass, methodId);

 

(*env)->CallVoidMethod(env, arg,methodId);

 

// Global reference

(*env)->GetJavaVM(env, &jvm);

     jObject =(*env)->NewGlobalRef(env, arg);

     c =(*env)->NewGlobalRef(env, bgpClass);

     m =(*env)->NewGlobalRef(env, methodId);

start(invoke_java_method);

(*env)->DeleteGlobalRef(env,c);             //手动销毁 global reference

(*env)->DeleteGlobalRef(env,m);            //手动销毁 global reference

(*env)->DeleteGlobalRef(env, jObject);

(*jvm)->DetachCurrentThread(jvm);        //销毁线程

(*jvm)->DestroyJavaVM(jvm);             //?销毁虚拟机

}

// Test method

JNIEXPORT void JNICALL Java_Invoker_println(JNIEnv *env, jobject obj, jstring string)

{

const char *str =(*env)->GetStringUTFChars(env, string, 0);

printf("[main] %s\n",str);

(*env)->ReleaseStringUTFChars(env,string, str);

}

// Callback method回调函数

int invoke_java_method ()

{

(*jvm)->AttachCurrentThread(jvm,(void**)&static_env, 0);          //获得当前线程可以使用的 JNIEnv *指针

   (*static_env)->CallVoidMethod(static_env, jObject, m);   //调用 Java 方法

printf("[callback] java methodinvoked, invoker class: %x ... \n", &jObject);

}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值