Calling a Java method from C++ via JNI problem.

Discussion in 'Java' started by Sambucus, Jun 28, 2005.

  1. Sambucus

    Sambucus Guest

    Hi all,
    I am having some real difficulties calling a Java method from C++
    code.

    I load my c++ dll from java using:

    static {
    System.loadLibrary("libname");
    }

    I then init the dll by calling a method in the c++ dll like this:
    (trying to save the references for env and obj)

    static JNIEnv *jEnv;
    static jobject jObj;

    JNIEXPORT void JNICALL Java_poker_jni_JavaClassName_init(JNIEnv *env,
    jobject obj){
    jEnv = env;
    jObj = env->NewGlobalRef(obj);
    }


    I have a function in my dll which I want to call a method (void
    doTextOut(int i)) in my Java class that loaded the dll, it looks like
    this:

    void update(){

    jclass cls = jEnv->GetObjectClass(jObj);
    jmethodID mid = jEnv->GetMethodID(cls, "doTextOut", "(I)V");
    jEnv->CallVoidMethod(jObj, mid);

    }

    this method is called from my WndProc callback function.

    When I do this the JVM will crash.

    If I try to do exactly the same thing as update() in the JNIEXPORT
    void JNICALL Java_poker_jni_JavaClassName_init(JNIEnv *env, jobject
    obj) function it works!?! But the thing is that I really need to do it
    from update()

    Any suggestion on what I am doing wrong, or is this something that is
    not even possible to do with JNI?

    Any help would be greatly appreciated!

    Best Regards
    AET
     
    Sambucus, Jun 28, 2005
    #1
    1. Advertising

  2. On 28 Jun 2005 02:48:45 -0700, Sambucus wrote:
    > I then init the dll by calling a method in the c++ dll like this:
    > (trying to save the references for env and obj)
    >
    > static JNIEnv *jEnv;
    > static jobject jObj;
    >
    > JNIEXPORT void JNICALL Java_poker_jni_JavaClassName_init(JNIEnv *env,
    > jobject obj){
    > jEnv = env;
    > jObj = env->NewGlobalRef(obj);
    > }


    Don't attempt to save the JNIEnv pointer for use from a different
    context, it will crash as you have discovered. Read the documentation
    for the invocation API (at the end of the JNI spec) for information
    about this.

    Saving the object reference is ok, just remember to release the global
    reference when you no longer need it.

    > I have a function in my dll which I want to call a method (void
    > doTextOut(int i)) in my Java class that loaded the dll, it looks
    > like this:
    >
    > void update(){
    > jclass cls = jEnv->GetObjectClass(jObj);
    > jmethodID mid = jEnv->GetMethodID(cls, "doTextOut", "(I)V");
    > jEnv->CallVoidMethod(jObj, mid);
    > }


    You need to attach "this" thread to the JVM to get a valid JNIEnv* for
    use in this context. Use JNI_GetCreatedJavaVMs() and
    AttachCurrentThread(), part of the invocation API.

    /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, Jun 28, 2005
    #2
    1. Advertising

  3. Sambucus

    Guest

    Gordon Beaton wrote:
    > On 28 Jun 2005 02:48:45 -0700, Sambucus wrote:
    > > I then init the dll by calling a method in the c++ dll like this:
    > > (trying to save the references for env and obj)
    > >
    > > static JNIEnv *jEnv;
    > > static jobject jObj;
    > >
    > > JNIEXPORT void JNICALL Java_poker_jni_JavaClassName_init(JNIEnv *env,
    > > jobject obj){
    > > jEnv = env;
    > > jObj = env->NewGlobalRef(obj);
    > > }

    >
    > Don't attempt to save the JNIEnv pointer for use from a different
    > context, it will crash as you have discovered. Read the documentation
    > for the invocation API (at the end of the JNI spec) for information
    > about this.
    >
    > Saving the object reference is ok, just remember to release the global
    > reference when you no longer need it.
    >
    > > I have a function in my dll which I want to call a method (void
    > > doTextOut(int i)) in my Java class that loaded the dll, it looks
    > > like this:
    > >
    > > void update(){
    > > jclass cls = jEnv->GetObjectClass(jObj);
    > > jmethodID mid = jEnv->GetMethodID(cls, "doTextOut", "(I)V");
    > > jEnv->CallVoidMethod(jObj, mid);
    > > }

    >
    > You need to attach "this" thread to the JVM to get a valid JNIEnv* for
    > use in this context. Use JNI_GetCreatedJavaVMs() and
    > AttachCurrentThread(), part of the invocation API.
    >


    As an alternative you can also used the JNI_OnLoad function to save the
    JavaVM pointer, instead of using JNI_GetCreatedJavaVMs.

    http://java.sun.com/j2se/1.3/docs/guide/jni/jni-12.html#JNI_OnLoad


    > /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
     
    , Jun 28, 2005
    #3
  4. Sambucus

    Gitta Zahn Guest

    Gordon Beaton wrote:
    > On 28 Jun 2005 02:48:45 -0700, Sambucus wrote:
    >>void update(){
    >> jclass cls = jEnv->GetObjectClass(jObj);
    >> jmethodID mid = jEnv->GetMethodID(cls, "doTextOut", "(I)V");
    >> jEnv->CallVoidMethod(jObj, mid);
    >>}

    >
    > You need to attach "this" thread to the JVM to get a valid JNIEnv* for
    > use in this context. Use JNI_GetCreatedJavaVMs() and
    > AttachCurrentThread(), part of the invocation API.


    As alternative you could use the operation GetEnv()
    within the operation update()
    http://java.sun.com/j2se/1.4.2/docs/guide/jni/jni-12.html#GetEnv

    This is at least necessary if you have multiple native threads
    attached at the JVM.

    Gitta
     
    Gitta Zahn, Jun 28, 2005
    #4
    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,781
    Joseph Millar
    Aug 1, 2003
  2. Kalpesh Modha

    JNI Strings and Calling a Java Method.

    Kalpesh Modha, Dec 12, 2003, in forum: Java
    Replies:
    0
    Views:
    2,765
    Kalpesh Modha
    Dec 12, 2003
  3. Kalpesh Modha

    JNI Strings and Calling a Java Method

    Kalpesh Modha, Dec 14, 2003, in forum: Java
    Replies:
    0
    Views:
    648
    Kalpesh Modha
    Dec 14, 2003
  4. Replies:
    2
    Views:
    392
  5. Replies:
    0
    Views:
    270
Loading...

Share This Page