gcj.texi

来自「理解和实践操作系统的一本好书」· TEXI 代码 · 共 1,908 行 · 第 1/5 页

TEXI
1,908
字号
@subsection Object fieldsEach object contains an object header, followed by the instance fieldsof the class, in order.  The object header consists of a singlepointer to a dispatch or virtual function table.  (There may be extrafields @emph{in front of} the object, for example for memorymanagement, but this is invisible to the application, and thereference to the object points to the dispatch table pointer.)The fields are laid out in the same order, alignment, and size as inC++.  Specifically, 8-bit and 16-bit native types (@code{byte},@code{short}, @code{char}, and @code{boolean}) are @emph{not} widenedto 32 bits.  Note that the Java VM does extend 8-bit and 16-bit typesto 32 bits when on the VM stack or temporary registers.If you include the @code{gcjh}-generated header for aclass, you can access fields of Java classes in the @emph{natural}way.  For example, given the following Java class:@examplepublic class Int@{  public int i;  public Int (int i) @{ this.i = i; @}  public static Int zero = new Int(0);@}@end exampleyou can write:@example#include <gcj/cni.h>;#include <Int>;Int*mult (Int *p, jint k)@{  if (k == 0)    return Int::zero;  // @r{Static member access.}  return new Int(p->i * k);@}@end example@subsection Access specifiersCNI does not strictly enforce the Java accessspecifiers, because Java permissions cannot be directly mappedinto C++ permission.  Private Java fields and methods are mappedto private C++ fields and methods, but other fields and methodsare mapped to public fields and methods.@node Class Initialization@section Class InitializationJava requires that each class be automatically initialized at the time of the first active use.  Initializing a class involves initializing the static fields, running code in class initializer methods, and initializing base classes.  There may also be some implementation specific actions, such as allocating @code{String} objects corresponding to string literals inthe code.The GCJ compiler inserts calls to @code{JvInitClass} at appropriateplaces to ensure that a class is initialized when required.  The C++compiler does not insert these calls automatically---it is theprogrammer's responsibility to make sure classes are initialized.However, this is fairly painless because of the conventions assumed bythe Java system.First, @code{libgcj} will make sure a class is initialized before aninstance of that object is created.  This is one of theresponsibilities of the @code{new} operation.  This is taken care ofboth in Java code, and in C++ code.  When G++ sees a @code{new} of aJava class, it will call a routine in @code{libgcj} to allocate theobject, and that routine will take care of initializing the class.Note however that this does not happen for Java arrays; you mustallocate those using the appropriate CNI function.  It follows thatyou can access an instance field, or call an instance (non-static)method and be safe in the knowledge that the class and all of its baseclasses have been initialized.Invoking a static method is also safe.  This is because theJava compiler adds code to the start of a static method to make surethe class is initialized.  However, the C++ compiler does notadd this extra code.  Hence, if you write a native static methodusing CNI, you are responsible for calling @code{JvInitClass}before doing anything else in the method (unless you are sureit is safe to leave it out).Accessing a static field also requires the class of thefield to be initialized.  The Java compiler will generate codeto call @code{JvInitClass} before getting or setting the field.However, the C++ compiler will not generate this extra code,so it is your responsibility to make sure the class isinitialized before you access a static field from C++.@node Object allocation@section Object allocationNew Java objects are allocated using a@dfn{class instance creation expression}, e.g.:@examplenew @var{Type} ( ... )@end exampleThe same syntax is used in C++.  The main difference is thatC++ objects have to be explicitly deleted; in Java they areautomatically deleted by the garbage collector.Using @acronym{CNI}, you can allocate a new Java objectusing standard C++ syntax and the C++ compiler will allocatememory from the garbage collector.  If you have overloadedconstructors, the compiler will choose the correct oneusing standard C++ overload resolution rules.  @noindent For example:@examplejava::util::Hashtable *ht = new java::util::Hashtable(120);@end example@node Memory allocation@section Memory allocationWhen allocating memory in @acronym{CNI} methods it is best to handleout-of-memory conditions by throwing a Java exception.  Thesefunctions are provided for that purpose:@deftypefun void* JvMalloc (jsize @var{size})Calls malloc.  Throws @code{java.lang.OutOfMemoryError} if allocationfails.@end deftypefun@deftypefun void* JvRealloc (void* @var{ptr}, jsize @var{size})Calls realloc.  Throws @code{java.lang.OutOfMemoryError} ifreallocation fails.@end deftypefun@deftypefun void JvFree (void* @var{ptr})Calls free.@end deftypefun@node Arrays@section ArraysWhile in many ways Java is similar to C and C++, it is quite differentin its treatment of arrays.  C arrays are based on the idea of pointerarithmetic, which would be incompatible with Java's securityrequirements.  Java arrays are true objects (array types inherit from@code{java.lang.Object}).  An array-valued variable is one thatcontains a reference (pointer) to an array object.Referencing a Java array in C++ code is done using the@code{JArray} template, which as defined as follows:@exampleclass __JArray : public java::lang::Object@{public:  int length;@};template<class T>class JArray : public __JArray@{  T data[0];public:  T& operator[](jint i) @{ return data[i]; @}@};@end exampleThere are a number of @code{typedef}s which correspond to @code{typedef}s from the @acronym{JNI}.  Each is the type of an array holding objectsof the relevant type:@exampletypedef __JArray *jarray;typedef JArray<jobject> *jobjectArray;typedef JArray<jboolean> *jbooleanArray;typedef JArray<jbyte> *jbyteArray;typedef JArray<jchar> *jcharArray;typedef JArray<jshort> *jshortArray;typedef JArray<jint> *jintArray;typedef JArray<jlong> *jlongArray;typedef JArray<jfloat> *jfloatArray;typedef JArray<jdouble> *jdoubleArray;@end example@deftypemethod {template<class T>} T* elements (JArray<T> @var{array})This template function can be used to get a pointer to the elements ofthe @code{array}.  For instance, you can fetch a pointer to theintegers that make up an @code{int[]} like so:@exampleextern jintArray foo;jint *intp = elements (foo);@end exampleThe name of this function may change in the future.@end deftypemethod@deftypefun jobjectArray JvNewObjectArray (jsize @var{length}, jclass @var{klass}, jobject @var{init})This creates a new array whose elements have reference type.@code{klass} is the type of elements of the array and@code{init} is the initial value put into every slot in the array.@end deftypefun@exampleusing namespace java::lang;JArray<String *> *array  = (JArray<String *> *) JvNewObjectArray(length, &String::class$, NULL);@end example@subsection Creating arraysFor each primitive type there is a function which can be used tocreate a new array of that type.  The name of the function is of theform:@exampleJvNew@var{Type}Array@end example@noindent For example:@exampleJvNewBooleanArray@end example@noindent can be used to create an array of Java primitive boolean types.@noindent The following function definition is the template for all such functions:@deftypefun jbooleanArray JvNewBooleanArray (jint @var{length})Creates an array @var{length} indices long.@end deftypefun@deftypefun jsize JvGetArrayLength (jarray @var{array})Returns the length of the @var{array}.@end deftypefun@node Methods@section MethodsJava methods are mapped directly into C++ methods.The header files generated by @code{gcjh}include the appropriate method definitions.Basically, the generated methods have the same names and@emph{corresponding} types as the Java methods,and are called in the natural manner.@subsection OverloadingBoth Java and C++ provide method overloading, where multiplemethods in a class have the same name, and the correct one is chosen(at compile time) depending on the argument types.The rules for choosing the correct method are (as expected) more complicatedin C++ than in Java, but given a set of overloaded methodsgenerated by @code{gcjh} the C++ compiler will choosethe expected one.Common assemblers and linkers are not aware of C++ overloading,so the standard implementation strategy is to encode theparameter types of a method into its assembly-level name.This encoding is called @dfn{mangling},and the encoded name is the @dfn{mangled name}.The same mechanism is used to implement Java overloading.For C++/Java interoperability, it is important that both the Javaand C++ compilers use the @emph{same} encoding scheme.@subsection Static methodsStatic Java methods are invoked in @acronym{CNI} using the standardC++ syntax, using the @code{::} operator ratherthan the @code{.} operator.  @noindent For example:@examplejint i = java::lang::Math::round((jfloat) 2.3);@end example@noindent C++ method definition syntax is used to define a static native method.For example:@example#include <java/lang/Integer>java::lang::Integer*java::lang::Integer::getInteger(jstring str)@{  ...@}@end example@subsection Object ConstructorsConstructors are called implicitly as part of object allocationusing the @code{new} operator.  @noindent For example:@examplejava::lang::Integer *x = new java::lang::Integer(234);@end exampleJava does not allow a constructor to be a native method.This limitation can be coded round however because a constructorcan @emph{call} a native method.@subsection Instance methodsCalling a Java instance method from a C++ @acronym{CNI} method is done using the standard C++ syntax, e.g.:@example// @r{First create the Java object.}java::lang::Integer *x = new java::lang::Integer(234);// @r{Now call a method.}jint prim_value = x->intValue();if (x->longValue == 0)   ...@end example@noindent Defining a Java native instance method is also done the natural way:@example#include <java/lang/Integer.h>jdoublejava::lang:Integer::doubleValue()@{  return (jdouble) value;@}@end example@subsection Interface methodsIn Java you can call a method using an interface reference.  This issupported, but not completely.  @xref{Interfaces}.@node Strings@section Strings@acronym{CNI} provides a number of utility functions forworking with Java Java @code{String} objects.The names and interfaces are analogous to those of @acronym{JNI}.@deftypefun jstring JvNewString (const jchar* @var{chars}, jsize @var{len})Returns a Java @code{String} object with characters from the array of Unicode characters @var{chars} up to the index @var{len} in that array.@end deftypefun@deftypefun jstring JvNewStringLatin1 (const char* @var{bytes}, jsize @var{len})Returns a Java @code{String} made up of @var{len} bytes from @var{bytes}.@end deftypefun@deftypefun jstring JvNewStringLatin1 (const char* @var{bytes})As above but the length of the @code{String} is @code{strlen(@var{bytes})}.@end deftypefun@deftypefun jstring JvNewStringUTF (const char* @var{bytes})Returns a @code{String} which is made up of the UTF enc

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?