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

S

Sambucus

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
 
G

Gordon Beaton

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
 
C

castillo.bryan

Gordon said:
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.


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
 

Ask a Question

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

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,769
Messages
2,569,582
Members
45,057
Latest member
KetoBeezACVGummies

Latest Threads

Top