This is the mail archive of the java@gcc.gnu.org mailing list for the Java project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: Is cast (NonJavaObject*) to (long) legal for cni callback purposes?


Olivier de Mirleau writes:
 > Hi, I'm currently using a procedure described below to do c2j2c 
 > callbacks with cni.
 > It seems to work for now, but I'm not quite sure it's supposed to ALWAYS 
 > work.
 > 
 > I was wondering if maybe somebody more knowledgable could tell me if 
 > it's ok.
 > 
 > ============================
 > 
 > I want to be able to
 > 1. Create an instance of NonJavaClass in cpp code.
 > 2. Have cpp call java using cni.
 > 3. Have java do a callback to the original NonJavaClass instance using cni.
 > 
 > ============================
 > 
 > The way I do it is as follows:
 > 
 > 1. I cast the pointer to the NonJavaClass instance to a long and pass 
 > that as a jlong to java.
 > 2. When java wants to do the NonJavaClass callback,
 >         it provides the long, which in cpp then gets cast back to 
 > (NonJavaClass*)
 > 
 > More explicitly I have a file CppImplementation.java which
 > implements the public method doIt() using native cpp:
 > ------------------------------------------------------
 > public class CppImplementation
 > {
 >     public CppImplementation(long aLong) {theLong = aLong;}
 >     public final void doIt() {this.doItNative(theLong);}
 > 
 >     private final native void doItNative(long anAddress);
 >     private long theLong;
 > }
 > -----------------------------------------------------------
 > And the private native method is implemented in cpp as follows:
 > ---------------------------------------------------------
 > 
 > #include "CppImplementation.h" // generated by gcjh
 > #include <stdio.h>
 > #include "NonJavaObject.cc"
 > 
 > void CppImplementation::doItNative (jlong anAddress )
 > {
 >   long myLong = (long) anAddress;
 >   NonJavaClass* myObject = (NonJavaClass*) myLong;
 >   printf("c2j2c callback: %d, %f\n", myLong, myObject->theBla);
 > }
 > ----------------------------------------------------------
 > The whole thing gets called as follows:
 > ----------------------------------------------------------
 > void myMain()
 > {
 >   NonJavaClass myNonJavaObject;
 >   myNonJavaObject.theBla = 5.0;
 >   long myLong = (long) (&myNonJavaObject);
 >   CppImplementation* myObject = new CppImplementation((jlong) myLong);
 >   myObject->doIt();
 > }
 > 
 > =====================================
 > 
 > My question is: Can I do that?

Yes.  Lots of large applications, in particular Eclipse, rely on this.

 > Or can it happen that the operating system every now and then
 > relocates memory and updates a known set of pointers in a smart way
 > and that the 'long' variable wouldn't get updated accordingly?

No.  C++ can't do that.  

 > Actually the question has nothing to do with java or cni, I might as well
 > have asked the question in a pure cpp context, namely whether
 > it's safe in the first place to cast from pointer to long and back a 
 > [little] later.

Well, according to the C++ standard it isn't safe to do that, but it
is safe to go that in GNU C++.  You'd be writing non-portable code.
But it's CNI, so it's already non-portable anyway.

Andrew.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]