Vijayk said:
Let me make this clearer. I have three components... a Java method that
I am trying to make a callback against, a C++ Dll that calls the Java
method, and a C++ Client that calls the C++ DLL. When I call the C++
DLL function via the C++ Client, I want the C++ DLL to call into the
Java Method and then have the Java Method return a Hashtable or generic
object structure back to the C++ DLL Function via JNI.
Right. You have a C++ program, which uses a C++ DLL, which in turn will call
JNI. In that case it's all quite easy (subject to one caveat, below).
Ignoring the issue of the intermediate DLL for a moment, all you do is create a
JVM instance (with CreateJavaVM()) which will live for the duration of your
program. That will provide you with a handle to the JVM object which you
should keep in a global. It will also provide you with a JNIEnv which it is
probably better to ignore unless you know that all accesses to Java will come
from the (OS) thread that created the JVM. When you want to call Java you use
GetEnv() or AttatchThread() (iirc) to find the right JNIEnv to use from that
thread (or save and use the original JNIEnv if you know you will be
single-threaded). Then you can use the JNIEnv in just the same way as is
described in Sun's JNI tutuorial.
(BTW, if you haven't already worked through that tutorial then I /stongly/
advise doing so).
One thing to note is that the tutorial (and much other JNI documentation)
assumes that Java code will be calling C/C++ code, not the other way around.
In general it doesn't make much difference, but you do have to note that the
automatic cleanup of (non-globabl) "references" doesn't happen if C is calling
Java (that cleanup happens as the C code returns to the JNI glue code in the
JVM, so if you don't return back to Java then cleanup does not happen). That
means that you have to be careful to release any references you use, and also
to keep track of how many you are using and not allow that to grow beyond what
the JVM expects.
Sheng Liang's book is pretty helpful. If you don't have it already, you can
download it (free) from:
http://java.sun.com/docs/books/jni/index.html
and that page also has the usual links for buying a physical copy.
Now for the caveat I mentioned above. I have never invoked the JVM from inside
a DLL, so there may be difficulties I don't know about. One obvious issue is
that you'll have to find an appropriate time to create the JVM (remembering
that you are only ever allowed to create one JMV in the lifetime of one
program). Another problem is that you will not necessarily be in control of
threading, so you'll have to take extra care to follow the JNI rules on
threading (see the book). Such issues aside, it's all pretty
straight-forward -- you just have to take a bit of care to read the
documentation and follow the rules.
-- chris