This is the mail archive of the
java@gcc.gnu.org
mailing list for the Java project.
Re: GCJ and C++ (calling Java from C++)
- From: Bryce McKinlay <mckinlay at redhat dot com>
- To: Lothar Werzinger <lothar at tradescape dot biz>
- Cc: java at gcc dot gnu dot org
- Date: Wed, 30 Nov 2005 23:56:24 -0500
- Subject: Re: GCJ and C++ (calling Java from C++)
- References: <200511281612.37450.lothar@tradescape.biz> <200511301558.02459.lothar@tradescape.biz> <438E488E.1020008@redhat.com> <200511301716.43813.lothar@tradescape.biz>
Lothar Werzinger wrote:
As a workaround, you can cast your object reference to the interface
type (using a C++ static_cast, for example), and then call the interface
method on that. Just be careful that the object you are casting really
does implement the interface!
I'm not sure what you suggest here. If you look at the C++ code I use you'll
notice that I call a static Method that returns a Java Object of type
Library. What goes wrong is if I call any method on the returned object.
As I already get a Library object I don't know what a cast would do different.
OK, this case should work. The header for your interfaces should have an
__attribute__ ((java_interface)) directive at the end of the
declaration. This tells C++ to generate a Java interface call, instead
of a virtual call. As an example: libgcj's java/io/natFilePosix.cc does
this - it calls the FilenameFilter interface to implement list().
If something is going wrong here, it may help to see a "c++ -S" asm dump
for the c++ method in question, along with the full header for the
interface you are calling.
bug 15411 is a different issue, as in that case it can actually generate
a broken virtual call because C++'s idea of the vtable layout will be
different from reality. 15411 shouldn't effect you in this case because
there is no abstract class here.
Bryce
Well it is similar in the sense that if gcjh does not generate the inheritance
relationship I suppose it also generates a wrong vtable, as inheritance
(inheriting virtual methods from interfaces) does affect the vtable - right?
No, because interface calls are implemented differently to virtual calls
- they do not use a vtable. All that is needed to complete an interface
call is the index of a method within that interface itself, declarations
from super-interfaces are not important. With for virtual calls, getting
this information wrong means the vtable layout is messed up, but for
interface calls it doesn't matter, provided the order of methods in the
header matches those that actually exist at runtime.
What we lose by not having the inheritance information represented in
C++ is the ability to call, on an interface, a method declared in some
super-interface without first casting the interface reference.
For example, say you have "interface Library implements Addressable" and
foo() is declared in Addressable. If you have a reference to a Library,
then you first need to cast to Addressable in order to call foo().
I wonder if we couldn't write a Java program that uses Java reflection to
generate the (correct) C++ headers. I guess it would probably much easier to
do that in Java than in C and we could use gcj to generate the gcjh
executable from the Java code.
There is no "correct" C++ header you could generate that would give you
this feature without changing the C++ compiler as well. gcjh needs to
change to provide the inheritance information, _and_ the C++ front end
needs to change to do something with that information.
Bryce