How to convert a C++ Object to a JNI jobject in order to use GetObjectClass

V

Vijayk

I have an interface object of type ISubscribe and I am trying to cast
the ISubscribe object to a jobject so I can call GetObjectClass in
order to proceed with a callback using JNI.

ISubscribe * s
jclass cls = env->GetObjectClass(s);


Does anyone know how I can do this in C++? I tried using
reinterpret_cast<jobject>(s) but GetObjectClass does not like that. Any
ideas would be appreciated.

Thanks,

Vijayk
 
R

Roedy Green

I have an interface object of type ISubscribe and I am trying to cast
the ISubscribe object to a jobject so I can call GetObjectClass in
order to proceed with a callback using JNI.

A Java object cast is like a C++ object cast with an extra check that
the object truly can be safely cast. This suggests you might be able
to use a C++ cast and live dangerously.

Cast is not indexed in my JNI text.
 
T

Thomas Hawtin

Roedy said:
A Java object cast is like a C++ object cast with an extra check that
the object truly can be safely cast. This suggests you might be able
to use a C++ cast and live dangerously.

There are a number of casts in C++. dynamic_cast<>() is much the same as
a Java cast (at least for "C" pointer types).

Tom Hawtin
 
C

Chris Uppal

Vijayk said:
I have an interface object of type ISubscribe and I am trying to cast
the ISubscribe object to a jobject so I can call GetObjectClass in
order to proceed with a callback using JNI.

??

What do you mean "I have an interface object" ? What sort of interface ? An
instance of a Java interface (you can't have, there is no such thing). A C++
object that is an instance of some C++ class that is being used as an interface
? A handle on a Windows COM object ? Something else ?

In none of these cases does the JNI function GetObjectClass() make any sense.
The nearest thing I can think of to what you are saying that does make sense,
is that you have a reference to a Java object with a statically declared type
which is a Java interface type. If so, then that is actually a reference to a
Java /object/ (i.e. an instance of some subclass of java.lang.Object). So just
call GetObjectClass() on it.

-- chris
 
V

Vijayk

I am trying to make a callback from a C++ client to a java method via a
C++ DLL. By Interface, I meant I have a dummy interface in the C++ DLL
that will be used to call GetObjectClass. My hypothesis is that the
Object from the Java Server will call back into the C++ Dll where I can
then use it. If anyone has any ideas about how callbacks work from a
C++ Client / Java Server POV that would be great.

Thanks,

Vijayk
 
C

Chris Uppal

Vijayk said:
I am trying to make a callback from a C++ client to a java method via a
C++ DLL. By Interface, I meant I have a dummy interface in the C++ DLL
that will be used to call GetObjectClass. My hypothesis is that the
Object from the Java Server will call back into the C++ Dll where I can
then use it.

I'm sorry but I can't follow that at all. I'm not sure what you mean by
"client" and "server", and I still don't see how a C++ interface can be used to
call GetObjectClass().

If anyone has any ideas about how callbacks work from a
C++ Client / Java Server POV that would be great.

I don't know if this will help at all, since I'm still confused about what you
are trying to do. The following /may/ help or it may be completely
irrelevant...

There is /only one/ way that Java code can invoke C++ code. You provide the
implementation of one or more "native" methods. That's all, there are no other
ways. And the implementation of the native method /must/ take the correct
arguments and have the right return type. There is no flexibility at all.
There are two ways of specifying the implementation of a native method. One is
to export functions from your DLL which have names that precisely match what
the Java runtime will expect to find (the names generated by the javah tool).
The other (which I prefer as simpler, less fragile, and marginally more
flexible) is to tell the Java runtime explicity which function to call by using
the RegisterNatives() function. It rather sounds as if you are expecting more
flexibility that that, if so then you'll have to use some ingenuity to code
around the restrictions. As far as I know, it is always possible to do so (at
least /I/ have never found a situation that I couldn't map onto JNI semantics)
but it may take more messing around than you want or, perhaps, expected. I
can't make any concrete suggestions because -- as I said -- I don't yet
understand what you are trying to do.

-- chris
 
V

Vijayk

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.

You also mentioned that I am trying to have Java code invoke C++ Code.
I am actually trying to do the transpose of that. I have a set of Java
methods that I am trying to call via a C++ DLL.

Please let me know if you need any clarification.

Thanks again for all your help.

vijayk
 
R

Roedy Green

Let me make this clearer. I have three components... a Java method that
I am trying to make a callback against,

Java does not have callbacks. It has delegate objects. So
translating your request, how does C++ call a Java method of a Java
delegate object passed to it as a parameter. See
http://mindprod.com/jgloss/delegate.html

The same way it would call any java instance method.

JNI is a can of worms. Unfortunately, it is not something that can be
explained in anything short of a small textbook. I give you a bare
bones start at http://mindprod.com/jgloss/jni.html
but I strongly recommend getting hold of a textbook to sort this out.
 
C

Chris Uppal

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
 
V

Vijayk

Chris,

Thanks for your response. However, I am able to create the JVM without
any problems in my C++ DLL. However, I am still a little confused about
how to make a "callback" from a Wrapper function in my C++ DLL that
calls a Java method. I am assuming once I make the call into the java
method, the java method will return some sort of generic object for me
to use in my C++ function within the C++ DLL. If anyone has done any
JNI work going from a C++ Client to a Java method, your input would be
greatly appreciated.

Thanks,

Vijayk
 
R

Roedy Green

I am assuming once I make the call into the java
method, the java method will return some sort of generic object for me
to use in my C++ function within the C++ DLL. If anyone has done any
JNI work going from a C++ Client to a Java method, your input would be
greatly appreciated.

Did you read the essay explaining Java delegate/callback's yet?

http://mindprod.com/jgloss/callback.html
 

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

No members online now.

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,009
Latest member
GidgetGamb

Latest Threads

Top