call Java method from C (JNI)

Discussion in 'Java' started by lionel pacoud, Feb 3, 2004.

  1. 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
     
    lionel pacoud, Feb 3, 2004
    #1
    1. Advertising

  2. 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
     
    Gordon Beaton, Feb 3, 2004
    #2
    1. Advertising

  3. 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;
    }
     
    lionel pacoud, Feb 4, 2004
    #3
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Jabel D. Morales - VMan of Mana

    Problems with JNI: calling a Java method from native method.

    Jabel D. Morales - VMan of Mana, Aug 1, 2003, in forum: Java
    Replies:
    1
    Views:
    4,790
    Joseph Millar
    Aug 1, 2003
  2. Richard B. Christ

    Proxying the call to a JNI method

    Richard B. Christ, Aug 4, 2004, in forum: Java
    Replies:
    1
    Views:
    345
    Jim Sculley
    Aug 5, 2004
  3. Replies:
    13
    Views:
    6,089
  4. Replies:
    2
    Views:
    811
  5. bgabrhelik
    Replies:
    0
    Views:
    819
    bgabrhelik
    Sep 29, 2009
Loading...

Share This Page