All Java classes are derived from java.lang.Object
. C++ does
not have a unique root class, but we use the C++ class
java::lang::Object
as the C++ version of the
java.lang.Object
Java class. All other Java classes are mapped
into corresponding C++ classes derived from java::lang::Object
.
Interface inheritance (the implements
keyword) is currently not
reflected in the C++ mapping.
Each object contains an object header, followed by the instance fields of the class, in order. The object header consists of a single pointer to a dispatch or virtual function table. (There may be extra fields in front of the object, for example for memory management, but this is invisible to the application, and the reference to the object points to the dispatch table pointer.)
The fields are laid out in the same order, alignment, and size as in
C++. Specifically, 8-bit and 16-bit native types (byte
,
short
, char
, and boolean
) are not widened
to 32 bits. Note that the Java VM does extend 8-bit and 16-bit types
to 32 bits when on the VM stack or temporary registers.
If you include the gcjh
-generated header for a
class, you can access fields of Java classes in the natural
way. For example, given the following Java class:
public class Int { public int i; public Int (int i) { this.i = i; } public static Int zero = new Int(0); }
you can write:
#include <gcj/cni.h>;
#include <Int>;
Int*
mult (Int *p, jint k)
{
if (k == 0)
return Int::zero; // Static member access.
return new Int(p->i * k);
}
CNI does not strictly enforce the Java access specifiers, because Java permissions cannot be directly mapped into C++ permission. Private Java fields and methods are mapped to private C++ fields and methods, but other fields and methods are mapped to public fields and methods.