• Post Reply Bookmark Topic Watch Topic
  • New Topic

Problem/Question accessing JNIEnv in diff. native threads of JNI app

 
Dan Bizman
Ranch Hand
Posts: 387
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I have C++ method that's called from Java. In this method, it creates a new thread to be used as a callback by a native event-raising method. In that thread, I want to be able to call a method on my object passed in to the original method. How do i do this?

From what i understand, I need to get the VM and cache it, then in the new thread, get an env pointer and call AttachCurrentThread, or something like that. But I can't find any info on how/where to cache the VM.

my method:


How do I do this?
 
Dan Bizman
Ranch Hand
Posts: 387
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
OK, I'm quite a bit further with this, but still not sure how to save a jobject (or even get it again).

Right now, I'm able to get/use the env. Here's what to do for that:

1. Implement:

JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void *reserved);
And save the VM in there.

2. Try to get env from VM, if return == JNI_EDETACHED (Yes, it has an extra "e" in there, it's not misspelled), then call:

vm->AttachCurrentThread( ( void ** ) &env, NULL );

then you call vm->GetEnv(...) again, and this time it should work.

Here's where i'm stuck. How do i get that jobject passed into my first method? When i try saving it and accessing that saved variable, I get a C++ runtime error about accessing memory that's not there.

What do I do?
 
Ernest Friedman-Hill
author and iconoclast
Sheriff
Posts: 24213
35
Chrome Eclipse IDE Mac OS X
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Java object references that are returned by most JNI library functions, or passed into your native method implementations as parameters are local references. A local reference can't be used in another thread or even outside of the method where it was created.

On the other hand, a global reference can be shared and passed all around. So before saving a reference to an object in a C static variable, use the NewGlobalRef() JNI library function to turn your local reference into a global reference, and you'll be all set.
 
Dan Bizman
Ranch Hand
Posts: 387
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Originally posted by Ernest Friedman-Hill:
Java object references that are returned by most JNI library functions, or passed into your native method implementations as parameters are local references. A local reference can't be used in another thread or even outside of the method where it was created.

On the other hand, a global reference can be shared and passed all around. So before saving a reference to an object in a C static variable, use the NewGlobalRef() JNI library function to turn your local reference into a global reference, and you'll be all set.


yep, I just found that a few minutes ago and it worked! Thanks!

Man, the documentation on JNI is very hard to find (and yes, with good reason but still...).
 
  • Post Reply Bookmark Topic Watch Topic
  • New Topic
Boost this thread!