Velocity Reviews

Velocity Reviews (http://www.velocityreviews.com/forums/index.php)
-   Java (http://www.velocityreviews.com/forums/f30-java.html)
-   -   call Java method from C (JNI) (http://www.velocityreviews.com/forums/t130983-call-java-method-from-c-jni.html)

lionel pacoud 02-03-2004 06:21 PM

call Java method from C (JNI)
 
I have a pb.
i'd like to store the ref. of a Java object in my C file and re use
it later.
when I try to re use it I obtain a Exception_access_violation

I join th code of my C file. If someone could help me.

-----------------
#include "timerFunction.h"
#include "com_scalpel_JNI_BackgroundFunction.h"

/* private field */
static JNIEnv *timer_global_env = NULL;
static jobject timer_global_obj = NULL;
static jclass timer_global_class = NULL;

void initTimer(JNIEnv *env, jobject obj) {
timer_global_env = env;
timer_global_obj = obj;

/* get object concerned */
jclass localRef_class =
(*timer_global_env)->GetObjectClass(timer_global_env,
timer_global_obj);
if (localRef_class == 0)
printf("NATIVE : error, unable to have local ref\n");

/* get an absolute ref on the object, the local one is lost at the
end of the function call */
timer_global_class =
(*timer_global_env)->NewGlobalRef(timer_global_env, localRef_class);
if (timer_global_class == 0)
printf("NATIVE : error, unable to have global ref\n");
}

void setTimer(int ms, void(* callback)(void)) {
timerStop = callback;
// get the method

global_mid = (*timer_global_env)->GetMethodID(timer_global_env,
timer_global_class, "throwSetTimer", "()V");
if (global_mid == 0) {
printf("NATIVE : method not found\n");
return;
}

(*timer_global_env)->CallVoidMethod(timer_global_env,
timer_global_obj, global_mid);
return;
}
....
}

---------

thank you very much for your help.
Lionel

Gordon Beaton 02-03-2004 06:41 PM

Re: call Java method from C (JNI)
 
On 3 Feb 2004 10:21:56 -0800, lionel pacoud wrote:
> i'd like to store the ref. of a Java object in my C file and re use
> it later. when I try to re use it I obtain a
> Exception_access_violation


The error isn't due to the object reference. You've correctly stored a
global reference to the object in question.

The problem is that you try to reuse the JNIEnv*, which is specific to
the thread it was created for by the JVM.

If you want to call Java methods from a callback thread, you need to
use JNI_GetCreatedJavaVMs() and AttachCurrentThread() from *that*
thread to get a valid JNIEnv*. These functions are described in the
invocation section of the JNI spec.

/gordon

--
[ do not email me copies of your followups ]
g o r d o n + n e w s @ b a l d e r 1 3 . s e

lionel pacoud 02-04-2004 09:51 AM

Re: call Java method from C (JNI)
 
I succed, I love the tast of the victory
First, Gordon, I really want to thanks you for your help

here is the exact solution of my pb. maybe it could be usefull for
some body else :


--------------------

/* private field */
static jobject timer_global_obj = NULL;
static jclass timer_global_class = NULL;
static JavaVM *global_jvm = NULL;

void initTimer(JNIEnv *env, jobject obj) {
// get global ref for the object and keep it
timer_global_obj = (*env)->NewGlobalRef(env, obj);;
// get global ref for the JVM and keep it
(*env)->GetJavaVM(env, &global_jvm);


// get object concerned
jclass localRef_class = (*env)->GetObjectClass(env,
timer_global_obj);
if (localRef_class == 0)
printf("NATIVE : error, unable to have local ref\n");

/* get an absolute ref on the object, the local one is lost at the
end of the function call */
timer_global_class = (*env)->NewGlobalRef(env, localRef_class);
if (timer_global_class == 0)
printf("NATIVE : error, unable to have global ref\n");
}

void setTimer(int ms, void(* callback)(void)) {
JNIEnv *jenv = NULL;
jmethodID mid = NULL;
jsize count;

timerStop = callback;
printf("NATIVE : timerFunction, setTimer\n");

// the Java thread and the C one are not the same so re find the
good JNIEnv
if (!(*global_jvm)->AttachCurrentThread(global_jvm, (void
**)&jenv, NULL)) {
// get the method
mid = (*jenv)->GetMethodID(jenv, timer_global_class, "throwSetTimer",
"(I)V");
printf("NATIVE : getMethodID succed\n");
if (mid == 0) {
printf("NATIVE : method not found\n");
return;
}
printf("NATIVE : try to call method\n");
(*jenv)->CallVoidMethod(jenv, timer_global_obj, mid, ms);
printf("NATIVE : call method succed\n");
}
return;
}


All times are GMT. The time now is 11:03 PM.

Powered by vBulletin®. Copyright ©2000 - 2014, vBulletin Solutions, Inc.
SEO by vBSEO ©2010, Crawlability, Inc.