This is the mail archive of the
java@gcc.gnu.org
mailing list for the Java project.
Re: Is cast (NonJavaObject*) to (long) legal for cni callback purposes?
- From: Andrew Haley <aph at redhat dot com>
- To: Olivier de Mirleau <odmi at imc dot nl>
- Cc: java at gcc dot gnu dot org
- Date: Fri, 23 Jun 2006 16:57:25 +0100
- Subject: Re: Is cast (NonJavaObject*) to (long) legal for cni callback purposes?
- References: <449C0D01.7050805@imc.nl>
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.