| 1 | <!DOCTYPE article PUBLIC "-//Davenport//DTD DocBook V3.0//EN"> | 
|---|
| 2 | <article> | 
|---|
| 3 | <artheader> | 
|---|
| 4 | <title>The Cygnus Native Interface for C++/Java Integration</title> | 
|---|
| 5 | <subtitle>Writing native Java methods in natural C++</subtitle> | 
|---|
| 6 | <authorgroup> | 
|---|
| 7 | <corpauthor>Cygnus Solutions</corpauthor> | 
|---|
| 8 | </authorgroup> | 
|---|
| 9 | <date>March, 2000</date> | 
|---|
| 10 | </artheader> | 
|---|
| 11 |  | 
|---|
| 12 | <abstract><para> | 
|---|
| 13 | This documents CNI, the Cygnus Native Interface, | 
|---|
| 14 | which is is a convenient way to write Java native methods using C++. | 
|---|
| 15 | This is a more efficient, more convenient, but less portable | 
|---|
| 16 | alternative to the standard JNI (Java Native Interface).</para> | 
|---|
| 17 | </abstract> | 
|---|
| 18 |  | 
|---|
| 19 | <sect1><title>Basic Concepts</title> | 
|---|
| 20 | <para> | 
|---|
| 21 | In terms of languages features, Java is mostly a subset | 
|---|
| 22 | of C++.  Java has a few important extensions, plus a powerful standard | 
|---|
| 23 | class library, but on the whole that does not change the basic similarity. | 
|---|
| 24 | Java is a hybrid object-oriented language, with a few native types, | 
|---|
| 25 | in addition to class types.  It is class-based, where a class may have | 
|---|
| 26 | static as well as per-object fields, and static as well as instance methods. | 
|---|
| 27 | Non-static methods may be virtual, and may be overloaded.  Overloading is | 
|---|
| 28 | resolved at compile time by matching the actual argument types against | 
|---|
| 29 | the parameter types.  Virtual methods are implemented using indirect calls | 
|---|
| 30 | through a dispatch table (virtual function table).  Objects are | 
|---|
| 31 | allocated on the heap, and initialized using a constructor method. | 
|---|
| 32 | Classes are organized in a package hierarchy. | 
|---|
| 33 | </para> | 
|---|
| 34 | <para> | 
|---|
| 35 | All of the listed attributes are also true of C++, though C++ has | 
|---|
| 36 | extra features (for example in C++ objects may be allocated not just | 
|---|
| 37 | on the heap, but also statically or in a local stack frame).  Because | 
|---|
| 38 | <acronym>gcj</acronym> uses the same compiler technology as | 
|---|
| 39 | <acronym>g++</acronym> (the GNU C++ compiler), it is possible | 
|---|
| 40 | to make the intersection of the two languages use the same | 
|---|
| 41 | <acronym>ABI</acronym> (object representation and calling conventions). | 
|---|
| 42 | The key idea in <acronym>CNI</acronym> is that Java objects are C++ objects, | 
|---|
| 43 | and all Java classes are C++ classes (but not the other way around). | 
|---|
| 44 | So the most important task in integrating Java and C++ is to | 
|---|
| 45 | remove gratuitous incompatibilities. | 
|---|
| 46 | </para> | 
|---|
| 47 | <para> | 
|---|
| 48 | You write CNI code as a regular C++ source file.  (You do have to use | 
|---|
| 49 | a Java/CNI-aware C++ compiler, specifically a recent version of G++.)</para> | 
|---|
| 50 | <para> | 
|---|
| 51 | You start with: | 
|---|
| 52 | <programlisting> | 
|---|
| 53 | #include <gcj/cni.h> | 
|---|
| 54 | </programlisting></para> | 
|---|
| 55 |  | 
|---|
| 56 | <para> | 
|---|
| 57 | You then include header files for the various Java classes you need | 
|---|
| 58 | to use: | 
|---|
| 59 | <programlisting> | 
|---|
| 60 | #include <java/lang/Character.h> | 
|---|
| 61 | #include <java/util/Date.h> | 
|---|
| 62 | #include <java/lang/IndexOutOfBoundsException.h> | 
|---|
| 63 | </programlisting></para> | 
|---|
| 64 |  | 
|---|
| 65 | <para> | 
|---|
| 66 | In general, <acronym>CNI</acronym> functions and macros start with the | 
|---|
| 67 | `<literal>Jv</literal>' prefix, for example the function | 
|---|
| 68 | `<literal>JvNewObjectArray</literal>'.  This convention is used to | 
|---|
| 69 | avoid conflicts with other libraries. | 
|---|
| 70 | Internal functions in <acronym>CNI</acronym> start with the prefix | 
|---|
| 71 | `<literal>_Jv_</literal>'.  You should not call these; | 
|---|
| 72 | if you find a need to, let us know and we will try to come up with an | 
|---|
| 73 | alternate solution.  (This manual lists <literal>_Jv_AllocBytes</literal> | 
|---|
| 74 | as an example;  <acronym>CNI</acronym> should instead provide | 
|---|
| 75 | a <literal>JvAllocBytes</literal> function.)</para> | 
|---|
| 76 | <para> | 
|---|
| 77 | These header files are automatically generated by <command>gcjh</command>. | 
|---|
| 78 | </para> | 
|---|
| 79 | </sect1> | 
|---|
| 80 |  | 
|---|
| 81 | <sect1><title>Packages</title> | 
|---|
| 82 | <para> | 
|---|
| 83 | The only global names in Java are class names, and packages. | 
|---|
| 84 | A <firstterm>package</firstterm> can contain zero or more classes, and | 
|---|
| 85 | also zero or more sub-packages. | 
|---|
| 86 | Every class belongs to either an unnamed package or a package that | 
|---|
| 87 | has a hierarchical and globally unique name. | 
|---|
| 88 | </para> | 
|---|
| 89 | <para> | 
|---|
| 90 | A Java package is mapped to a C++ <firstterm>namespace</firstterm>. | 
|---|
| 91 | The Java class <literal>java.lang.String</literal> | 
|---|
| 92 | is in the package <literal>java.lang</literal>, which is a sub-package | 
|---|
| 93 | of <literal>java</literal>.  The C++ equivalent is the | 
|---|
| 94 | class <literal>java::lang::String</literal>, | 
|---|
| 95 | which is in the namespace <literal>java::lang</literal>, | 
|---|
| 96 | which is in the namespace <literal>java</literal>. | 
|---|
| 97 | </para> | 
|---|
| 98 | <para> | 
|---|
| 99 | Here is how you could express this: | 
|---|
| 100 | <programlisting> | 
|---|
| 101 | // Declare the class(es), possibly in a header file: | 
|---|
| 102 | namespace java { | 
|---|
| 103 | namespace lang { | 
|---|
| 104 | class Object; | 
|---|
| 105 | class String; | 
|---|
| 106 | ... | 
|---|
| 107 | } | 
|---|
| 108 | } | 
|---|
| 109 |  | 
|---|
| 110 | class java::lang::String : public java::lang::Object | 
|---|
| 111 | { | 
|---|
| 112 | ... | 
|---|
| 113 | }; | 
|---|
| 114 | </programlisting> | 
|---|
| 115 | </para> | 
|---|
| 116 | <para> | 
|---|
| 117 | The <literal>gcjh</literal> tool automatically generates the | 
|---|
| 118 | nessary namespace declarations.</para> | 
|---|
| 119 |  | 
|---|
| 120 | <sect2><title>Nested classes as a substitute for namespaces</title> | 
|---|
| 121 | <para> | 
|---|
| 122 | <!-- FIXME the next line reads poorly jsm --> | 
|---|
| 123 | It is not that long since g++ got complete namespace support, | 
|---|
| 124 | and it was very recent (end of February 1999) that <literal>libgcj</literal> | 
|---|
| 125 | was changed to uses namespaces.  Releases before then used | 
|---|
| 126 | nested classes, which are the C++ equivalent of Java inner classes. | 
|---|
| 127 | They provide similar (though less convenient) functionality. | 
|---|
| 128 | The old syntax is: | 
|---|
| 129 | <programlisting> | 
|---|
| 130 | class java { | 
|---|
| 131 | class lang { | 
|---|
| 132 | class Object; | 
|---|
| 133 | class String; | 
|---|
| 134 | }; | 
|---|
| 135 | }; | 
|---|
| 136 | </programlisting> | 
|---|
| 137 | The obvious difference is the use of <literal>class</literal> instead | 
|---|
| 138 | of <literal>namespace</literal>.  The more important difference is | 
|---|
| 139 | that all the members of a nested class have to be declared inside | 
|---|
| 140 | the parent class definition, while namespaces can be defined in | 
|---|
| 141 | multiple places in the source.  This is more convenient, since it | 
|---|
| 142 | corresponds more closely to how Java packages are defined. | 
|---|
| 143 | The main difference is in the declarations; the syntax for | 
|---|
| 144 | using a nested class is the same as with namespaces: | 
|---|
| 145 | <programlisting> | 
|---|
| 146 | class java::lang::String : public java::lang::Object | 
|---|
| 147 | { ... } | 
|---|
| 148 | </programlisting> | 
|---|
| 149 | Note that the generated code (including name mangling) | 
|---|
| 150 | using nested classes is the same as that using namespaces.</para> | 
|---|
| 151 | </sect2> | 
|---|
| 152 |  | 
|---|
| 153 | <sect2><title>Leaving out package names</title> | 
|---|
| 154 | <para> | 
|---|
| 155 | <!-- FIXME next line reads poorly jsm --> | 
|---|
| 156 | Having to always type the fully-qualified class name is verbose. | 
|---|
| 157 | It also makes it more difficult to change the package containing a class. | 
|---|
| 158 | The Java <literal>package</literal> declaration specifies that the | 
|---|
| 159 | following class declarations are in the named package, without having | 
|---|
| 160 | to explicitly name the full package qualifiers. | 
|---|
| 161 | The <literal>package</literal> declaration can be followed by zero or | 
|---|
| 162 | more <literal>import</literal> declarations, which allows either | 
|---|
| 163 | a single class or all the classes in a package to be named by a simple | 
|---|
| 164 | identifier.  C++ provides something similar | 
|---|
| 165 | with the <literal>using</literal> declaration and directive. | 
|---|
| 166 | </para> | 
|---|
| 167 | <para> | 
|---|
| 168 | A Java simple-type-import declaration: | 
|---|
| 169 | <programlisting> | 
|---|
| 170 | import <replaceable>PackageName</replaceable>.<replaceable>TypeName</replaceable>; | 
|---|
| 171 | </programlisting> | 
|---|
| 172 | allows using <replaceable>TypeName</replaceable> as a shorthand for | 
|---|
| 173 | <literal><replaceable>PackageName</replaceable>.<replaceable>TypeName</replaceable></literal>. | 
|---|
| 174 | The C++ (more-or-less) equivalent is a <literal>using</literal>-declaration: | 
|---|
| 175 | <programlisting> | 
|---|
| 176 | using <replaceable>PackageName</replaceable>::<replaceable>TypeName</replaceable>; | 
|---|
| 177 | </programlisting> | 
|---|
| 178 | </para> | 
|---|
| 179 | <para> | 
|---|
| 180 | A Java import-on-demand declaration: | 
|---|
| 181 | <programlisting> | 
|---|
| 182 | import <replaceable>PackageName</replaceable>.*; | 
|---|
| 183 | </programlisting> | 
|---|
| 184 | allows using <replaceable>TypeName</replaceable> as a shorthand for | 
|---|
| 185 | <literal><replaceable>PackageName</replaceable>.<replaceable>TypeName</replaceable></literal> | 
|---|
| 186 | The C++ (more-or-less) equivalent is a <literal>using</literal>-directive: | 
|---|
| 187 | <programlisting> | 
|---|
| 188 | using namespace <replaceable>PackageName</replaceable>; | 
|---|
| 189 | </programlisting> | 
|---|
| 190 | </para> | 
|---|
| 191 | </sect2> | 
|---|
| 192 | </sect1> | 
|---|
| 193 |  | 
|---|
| 194 | <sect1><title>Primitive types</title> | 
|---|
| 195 | <para> | 
|---|
| 196 | Java provides 8 <quote>primitives</quote> types: | 
|---|
| 197 | <literal>byte</literal>, <literal>short</literal>, <literal>int</literal>, | 
|---|
| 198 | <literal>long</literal>, <literal>float</literal>, <literal>double</literal>, | 
|---|
| 199 | <literal>char</literal>, and <literal>boolean</literal>. | 
|---|
| 200 | These are the same as the following C++ <literal>typedef</literal>s | 
|---|
| 201 | (which are defined by <literal>gcj/cni.h</literal>): | 
|---|
| 202 | <literal>jbyte</literal>, <literal>jshort</literal>, <literal>jint</literal>, | 
|---|
| 203 | <literal>jlong</literal>, <literal>jfloat</literal>, | 
|---|
| 204 | <literal>jdouble</literal>, | 
|---|
| 205 | <literal>jchar</literal>, and <literal>jboolean</literal>. | 
|---|
| 206 | You should use the C++ typenames | 
|---|
| 207 | (<ForeignPhrase><Abbrev>e.g.</Abbrev></ForeignPhrase> <literal>jint</literal>), | 
|---|
| 208 | and not the Java types names | 
|---|
| 209 | (<ForeignPhrase><Abbrev>e.g.</Abbrev></ForeignPhrase> <literal>int</literal>), | 
|---|
| 210 | even if they are <quote>the same</quote>. | 
|---|
| 211 | This is because there is no guarantee that the C++ type | 
|---|
| 212 | <literal>int</literal> is a 32-bit type, but <literal>jint</literal> | 
|---|
| 213 | <emphasis>is</emphasis> guaranteed to be a 32-bit type. | 
|---|
| 214 |  | 
|---|
| 215 | <informaltable frame="all" colsep="1" rowsep="0"> | 
|---|
| 216 | <tgroup cols="3"> | 
|---|
| 217 | <thead> | 
|---|
| 218 | <row> | 
|---|
| 219 | <entry>Java type</entry> | 
|---|
| 220 | <entry>C/C++ typename</entry> | 
|---|
| 221 | <entry>Description</entry> | 
|---|
| 222 | </thead> | 
|---|
| 223 | <tbody> | 
|---|
| 224 | <row> | 
|---|
| 225 | <entry>byte</entry> | 
|---|
| 226 | <entry>jbyte</entry> | 
|---|
| 227 | <entry>8-bit signed integer</entry> | 
|---|
| 228 | </row> | 
|---|
| 229 | <row> | 
|---|
| 230 | <entry>short</entry> | 
|---|
| 231 | <entry>jshort</entry> | 
|---|
| 232 | <entry>16-bit signed integer</entry> | 
|---|
| 233 | </row> | 
|---|
| 234 | <row> | 
|---|
| 235 | <entry>int</entry> | 
|---|
| 236 | <entry>jint</entry> | 
|---|
| 237 | <entry>32-bit signed integer</entry> | 
|---|
| 238 | </row> | 
|---|
| 239 | <row> | 
|---|
| 240 | <entry>long</entry> | 
|---|
| 241 | <entry>jlong</entry> | 
|---|
| 242 | <entry>64-bit signed integer</entry> | 
|---|
| 243 | </row> | 
|---|
| 244 | <row> | 
|---|
| 245 | <entry>float</entry> | 
|---|
| 246 | <entry>jfloat</entry> | 
|---|
| 247 | <entry>32-bit IEEE floating-point number</entry> | 
|---|
| 248 | </row> | 
|---|
| 249 | <row> | 
|---|
| 250 | <entry>double</entry> | 
|---|
| 251 | <entry>jdouble</entry> | 
|---|
| 252 | <entry>64-bit IEEE floating-point number</entry> | 
|---|
| 253 | </row> | 
|---|
| 254 | <row> | 
|---|
| 255 | <entry>char</entry> | 
|---|
| 256 | <entry>jchar</entry> | 
|---|
| 257 | <entry>16-bit Unicode character</entry> | 
|---|
| 258 | </row> | 
|---|
| 259 | <row> | 
|---|
| 260 | <entry>boolean</entry> | 
|---|
| 261 | <entry>jboolean</entry> | 
|---|
| 262 | <entry>logical (Boolean) values</entry> | 
|---|
| 263 | </row> | 
|---|
| 264 | <row> | 
|---|
| 265 | <entry>void</entry> | 
|---|
| 266 | <entry>void</entry> | 
|---|
| 267 | <entry>no value</entry> | 
|---|
| 268 | </row> | 
|---|
| 269 | </tbody></tgroup> | 
|---|
| 270 | </informaltable> | 
|---|
| 271 | </para> | 
|---|
| 272 |  | 
|---|
| 273 | <para> | 
|---|
| 274 | <funcsynopsis> | 
|---|
| 275 | <funcdef><function>JvPrimClass</function></funcdef> | 
|---|
| 276 | <paramdef><parameter>primtype</parameter></paramdef> | 
|---|
| 277 | </funcsynopsis> | 
|---|
| 278 | This is a macro whose argument should be the name of a primitive | 
|---|
| 279 | type, <ForeignPhrase><Abbrev>e.g.</Abbrev></ForeignPhrase> | 
|---|
| 280 | <literal>byte</literal>. | 
|---|
| 281 | The macro expands to a pointer to the <literal>Class</literal> object | 
|---|
| 282 | corresponding to the primitive type. | 
|---|
| 283 | <ForeignPhrase><Abbrev>E.g.</Abbrev></ForeignPhrase>, | 
|---|
| 284 | <literal>JvPrimClass(void)</literal> | 
|---|
| 285 | has the same value as the Java expression | 
|---|
| 286 | <literal>Void.TYPE</literal> (or <literal>void.class</literal>). | 
|---|
| 287 | </para> | 
|---|
| 288 |  | 
|---|
| 289 | </sect1> | 
|---|
| 290 |  | 
|---|
| 291 | <sect1><title>Objects and Classes</title> | 
|---|
| 292 | <sect2><title>Classes</title> | 
|---|
| 293 | <para> | 
|---|
| 294 | All Java classes are derived from <literal>java.lang.Object</literal>. | 
|---|
| 295 | C++ does not have a unique <quote>root</quote>class, but we use | 
|---|
| 296 | a C++ <literal>java::lang::Object</literal> as the C++ version | 
|---|
| 297 | of the <literal>java.lang.Object</literal> Java class.  All | 
|---|
| 298 | other Java classes are mapped into corresponding C++ classes | 
|---|
| 299 | derived from <literal>java::lang::Object</literal>.</para> | 
|---|
| 300 | <para> | 
|---|
| 301 | Interface inheritance (the <quote><literal>implements</literal></quote> | 
|---|
| 302 | keyword) is currently not reflected in the C++ mapping.</para> | 
|---|
| 303 | </sect2> | 
|---|
| 304 | <sect2><title>Object references</title> | 
|---|
| 305 | <para> | 
|---|
| 306 | We implement a Java object reference as a pointer to the start | 
|---|
| 307 | of the referenced object.  It maps to a C++ pointer. | 
|---|
| 308 | (We cannot use C++ references for Java references, since | 
|---|
| 309 | once a C++ reference has been initialized, you cannot change it to | 
|---|
| 310 | point to another object.) | 
|---|
| 311 | The <literal>null</literal> Java reference maps to the <literal>NULL</literal> | 
|---|
| 312 | C++ pointer. | 
|---|
| 313 | </para> | 
|---|
| 314 | <para> | 
|---|
| 315 | Note that in some Java implementations an object reference is implemented as | 
|---|
| 316 | a pointer to a two-word <quote>handle</quote>.  One word of the handle | 
|---|
| 317 | points to the fields of the object, while the other points | 
|---|
| 318 | to a method table.  Gcj does not use this extra indirection. | 
|---|
| 319 | </para> | 
|---|
| 320 | </sect2> | 
|---|
| 321 | <sect2><title>Object fields</title> | 
|---|
| 322 | <para> | 
|---|
| 323 | Each object contains an object header, followed by the instance | 
|---|
| 324 | fields of the class, in order.  The object header consists of | 
|---|
| 325 | a single pointer to a dispatch or virtual function table. | 
|---|
| 326 | (There may be extra fields <quote>in front of</quote> the object, | 
|---|
| 327 | for example for | 
|---|
| 328 | memory management, but this is invisible to the application, and | 
|---|
| 329 | the reference to the object points to the dispatch table pointer.) | 
|---|
| 330 | </para> | 
|---|
| 331 | <para> | 
|---|
| 332 | The fields are laid out in the same order, alignment, and size | 
|---|
| 333 | as in C++.  Specifically, 8-bite and 16-bit native types | 
|---|
| 334 | (<literal>byte</literal>, <literal>short</literal>, <literal>char</literal>, | 
|---|
| 335 | and <literal>boolean</literal>) are <emphasis>not</emphasis> | 
|---|
| 336 | widened to 32 bits. | 
|---|
| 337 | Note that the Java VM does extend 8-bit and 16-bit types to 32 bits | 
|---|
| 338 | when on the VM stack or temporary registers.</para> | 
|---|
| 339 | <para> | 
|---|
| 340 | If you include the <literal>gcjh</literal>-generated header for a | 
|---|
| 341 | class, you can access fields of Java classes in the <quote>natural</quote> | 
|---|
| 342 | way.  Given the following Java class: | 
|---|
| 343 | <programlisting> | 
|---|
| 344 | public class Int | 
|---|
| 345 | { | 
|---|
| 346 | public int i; | 
|---|
| 347 | public Integer (int i) { this.i = i; } | 
|---|
| 348 | public static zero = new Integer(0); | 
|---|
| 349 | } | 
|---|
| 350 | </programlisting> | 
|---|
| 351 | you can write: | 
|---|
| 352 | <programlisting> | 
|---|
| 353 | #include <gcj/cni.h> | 
|---|
| 354 | #include <Int.h> | 
|---|
| 355 | Int* | 
|---|
| 356 | mult (Int *p, jint k) | 
|---|
| 357 | { | 
|---|
| 358 | if (k == 0) | 
|---|
| 359 | return Int::zero;  // static member access. | 
|---|
| 360 | return new Int(p->i * k); | 
|---|
| 361 | } | 
|---|
| 362 | </programlisting> | 
|---|
| 363 | </para> | 
|---|
| 364 | <para> | 
|---|
| 365 | <acronym>CNI</acronym> does not strictly enforce the Java access | 
|---|
| 366 | specifiers, because Java permissions cannot be directly mapped | 
|---|
| 367 | into C++ permission.  Private Java fields and methods are mapped | 
|---|
| 368 | to private C++ fields and methods, but other fields and methods | 
|---|
| 369 | are mapped to public fields and methods. | 
|---|
| 370 | </para> | 
|---|
| 371 | </sect2> | 
|---|
| 372 | </sect1> | 
|---|
| 373 |  | 
|---|
| 374 | <sect1><title>Arrays</title> | 
|---|
| 375 | <para> | 
|---|
| 376 | While in many ways Java is similar to C and C++, | 
|---|
| 377 | it is quite different in its treatment of arrays. | 
|---|
| 378 | C arrays are based on the idea of pointer arithmetic, | 
|---|
| 379 | which would be incompatible with Java's security requirements. | 
|---|
| 380 | Java arrays are true objects (array types inherit from | 
|---|
| 381 | <literal>java.lang.Object</literal>).  An array-valued variable | 
|---|
| 382 | is one that contains a reference (pointer) to an array object. | 
|---|
| 383 | </para> | 
|---|
| 384 | <para> | 
|---|
| 385 | Referencing a Java array in C++ code is done using the | 
|---|
| 386 | <literal>JArray</literal> template, which as defined as follows: | 
|---|
| 387 | <programlisting> | 
|---|
| 388 | class __JArray : public java::lang::Object | 
|---|
| 389 | { | 
|---|
| 390 | public: | 
|---|
| 391 | int length; | 
|---|
| 392 | }; | 
|---|
| 393 |  | 
|---|
| 394 | template<class T> | 
|---|
| 395 | class JArray : public __JArray | 
|---|
| 396 | { | 
|---|
| 397 | T data[0]; | 
|---|
| 398 | public: | 
|---|
| 399 | T& operator[](jint i) { return data[i]; } | 
|---|
| 400 | }; | 
|---|
| 401 | </programlisting></para> | 
|---|
| 402 | <para> | 
|---|
| 403 | <funcsynopsis> | 
|---|
| 404 | <funcdef>template<class T>  T *<function>elements</function></funcdef> | 
|---|
| 405 | <paramdef>JArray<T> &<parameter>array</parameter></paramdef> | 
|---|
| 406 | </funcsynopsis> | 
|---|
| 407 | This template function can be used to get a pointer to the | 
|---|
| 408 | elements of the <parameter>array</parameter>. | 
|---|
| 409 | For instance, you can fetch a pointer | 
|---|
| 410 | to the integers that make up an <literal>int[]</literal> like so: | 
|---|
| 411 | <programlisting> | 
|---|
| 412 | extern jintArray foo; | 
|---|
| 413 | jint *intp = elements (foo); | 
|---|
| 414 | </programlisting> | 
|---|
| 415 | The name of this function may change in the future.</para> | 
|---|
| 416 | <para> | 
|---|
| 417 | There are a number of typedefs which correspond to typedefs from JNI. | 
|---|
| 418 | Each is the type of an array holding objects of the appropriate type: | 
|---|
| 419 | <programlisting> | 
|---|
| 420 | typedef __JArray *jarray; | 
|---|
| 421 | typedef JArray<jobject> *jobjectArray; | 
|---|
| 422 | typedef JArray<jboolean> *jbooleanArray; | 
|---|
| 423 | typedef JArray<jbyte> *jbyteArray; | 
|---|
| 424 | typedef JArray<jchar> *jcharArray; | 
|---|
| 425 | typedef JArray<jshort> *jshortArray; | 
|---|
| 426 | typedef JArray<jint> *jintArray; | 
|---|
| 427 | typedef JArray<jlong> *jlongArray; | 
|---|
| 428 | typedef JArray<jfloat> *jfloatArray; | 
|---|
| 429 | typedef JArray<jdouble> *jdoubleArray; | 
|---|
| 430 | </programlisting> | 
|---|
| 431 | </para> | 
|---|
| 432 | <para> | 
|---|
| 433 | You can create an array of objects using this function: | 
|---|
| 434 | <funcsynopsis> | 
|---|
| 435 | <funcdef>jobjectArray <function>JvNewObjectArray</function></funcdef> | 
|---|
| 436 | <paramdef>jint <parameter>length</parameter></paramdef> | 
|---|
| 437 | <paramdef>jclass <parameter>klass</parameter></paramdef> | 
|---|
| 438 | <paramdef>jobject <parameter>init</parameter></paramdef> | 
|---|
| 439 | </funcsynopsis> | 
|---|
| 440 | Here <parameter>klass</parameter> is the type of elements of the array; | 
|---|
| 441 | <parameter>init</parameter> is the initial | 
|---|
| 442 | value to be put into every slot in the array. | 
|---|
| 443 | </para> | 
|---|
| 444 | <para> | 
|---|
| 445 | For each primitive type there is a function which can be used | 
|---|
| 446 | to create a new array holding that type.  The name of the function | 
|---|
| 447 | is of the form | 
|---|
| 448 | `<literal>JvNew<<replaceable>Type</replaceable>>Array</literal>', | 
|---|
| 449 | where `<<replaceable>Type</replaceable>>' is the name of | 
|---|
| 450 | the primitive type, with its initial letter in upper-case.  For | 
|---|
| 451 | instance, `<literal>JvNewBooleanArray</literal>' can be used to create | 
|---|
| 452 | a new array of booleans. | 
|---|
| 453 | Each such function follows this example: | 
|---|
| 454 | <funcsynopsis> | 
|---|
| 455 | <funcdef>jbooleanArray <function>JvNewBooleanArray</function></funcdef> | 
|---|
| 456 | <paramdef>jint <parameter>length</parameter></paramdef> | 
|---|
| 457 | </funcsynopsis> | 
|---|
| 458 | </para> | 
|---|
| 459 | <para> | 
|---|
| 460 | <funcsynopsis> | 
|---|
| 461 | <funcdef>jsize <function>JvGetArrayLength</function></funcdef> | 
|---|
| 462 | <paramdef>jarray <parameter>array</parameter></paramdef> | 
|---|
| 463 | </funcsynopsis> | 
|---|
| 464 | Returns the length of <parameter>array</parameter>.</para> | 
|---|
| 465 | </sect1> | 
|---|
| 466 |  | 
|---|
| 467 | <sect1><title>Methods</title> | 
|---|
| 468 |  | 
|---|
| 469 | <para> | 
|---|
| 470 | Java methods are mapped directly into C++ methods. | 
|---|
| 471 | The header files generated by <literal>gcjh</literal> | 
|---|
| 472 | include the appropriate method definitions. | 
|---|
| 473 | Basically, the generated methods have the same names and | 
|---|
| 474 | <quote>corresponding</quote> types as the Java methods, | 
|---|
| 475 | and are called in the natural manner.</para> | 
|---|
| 476 |  | 
|---|
| 477 | <sect2><title>Overloading</title> | 
|---|
| 478 | <para> | 
|---|
| 479 | Both Java and C++ provide method overloading, where multiple | 
|---|
| 480 | methods in a class have the same name, and the correct one is chosen | 
|---|
| 481 | (at compile time) depending on the argument types. | 
|---|
| 482 | The rules for choosing the correct method are (as expected) more complicated | 
|---|
| 483 | in C++ than in Java, but given a set of overloaded methods | 
|---|
| 484 | generated by <literal>gcjh</literal> the C++ compiler will choose | 
|---|
| 485 | the expected one.</para> | 
|---|
| 486 | <para> | 
|---|
| 487 | Common assemblers and linkers are not aware of C++ overloading, | 
|---|
| 488 | so the standard implementation strategy is to encode the | 
|---|
| 489 | parameter types of a method into its assembly-level name. | 
|---|
| 490 | This encoding is called <firstterm>mangling</firstterm>, | 
|---|
| 491 | and the encoded name is the <firstterm>mangled name</firstterm>. | 
|---|
| 492 | The same mechanism is used to implement Java overloading. | 
|---|
| 493 | For C++/Java interoperability, it is important that both the Java | 
|---|
| 494 | and C++ compilers use the <emphasis>same</emphasis> encoding scheme. | 
|---|
| 495 | </para> | 
|---|
| 496 | </sect2> | 
|---|
| 497 |  | 
|---|
| 498 | <sect2><title>Static methods</title> | 
|---|
| 499 | <para> | 
|---|
| 500 | Static Java methods are invoked in <acronym>CNI</acronym> using the standard | 
|---|
| 501 | C++ syntax, using the `<literal>::</literal>' operator rather | 
|---|
| 502 | than the `<literal>.</literal>' operator.  For example: | 
|---|
| 503 | </para> | 
|---|
| 504 | <programlisting> | 
|---|
| 505 | jint i = java::lang::Math::round((jfloat) 2.3); | 
|---|
| 506 | </programlisting> | 
|---|
| 507 | <para> | 
|---|
| 508 | <!-- FIXME this next sentence seems ungammatical jsm --> | 
|---|
| 509 | Defining a static native method uses standard C++ method | 
|---|
| 510 | definition syntax.  For example: | 
|---|
| 511 | <programlisting> | 
|---|
| 512 | #include <java/lang/Integer.h> | 
|---|
| 513 | java::lang::Integer* | 
|---|
| 514 | java::lang::Integer::getInteger(jstring str) | 
|---|
| 515 | { | 
|---|
| 516 | ... | 
|---|
| 517 | } | 
|---|
| 518 | </programlisting> | 
|---|
| 519 | </sect2> | 
|---|
| 520 |  | 
|---|
| 521 | <sect2><title>Object Constructors</title> | 
|---|
| 522 | <para> | 
|---|
| 523 | Constructors are called implicitly as part of object allocation | 
|---|
| 524 | using the <literal>new</literal> operator.  For example: | 
|---|
| 525 | <programlisting> | 
|---|
| 526 | java::lang::Int x = new java::lang::Int(234); | 
|---|
| 527 | </programlisting> | 
|---|
| 528 | </para> | 
|---|
| 529 | <para> | 
|---|
| 530 | <!-- FIXME rewrite needed here, mine may not be good jsm --> | 
|---|
| 531 | Java does not allow a constructor to be a native method. | 
|---|
| 532 | Instead, you could define a private method which | 
|---|
| 533 | you can have the constructor call. | 
|---|
| 534 | </para> | 
|---|
| 535 | </sect2> | 
|---|
| 536 |  | 
|---|
| 537 | <sect2><title>Instance methods</title> | 
|---|
| 538 | <para> | 
|---|
| 539 | <!-- FIXME next para week, I would remove a few words from some sentences jsm --> | 
|---|
| 540 | Virtual method dispatch is handled essentially the same way | 
|---|
| 541 | in C++ and Java -- <abbrev>i.e.</abbrev> by doing an | 
|---|
| 542 | indirect call through a function pointer stored in a per-class virtual | 
|---|
| 543 | function table.  C++ is more complicated because it has to support | 
|---|
| 544 | multiple inheritance, but this does not effect Java classes. | 
|---|
| 545 | However, G++ has historically used a different calling convention | 
|---|
| 546 | that is not compatible with the one used by <acronym>gcj</acronym>. | 
|---|
| 547 | During 1999, G++ will switch to a new ABI that is compatible with | 
|---|
| 548 | <acronym>gcj</acronym>.  Some platforms (including Linux) have already | 
|---|
| 549 | changed.  On other platforms, you will have to pass | 
|---|
| 550 | the <literal>-fvtable-thunks</literal> flag to g++ when | 
|---|
| 551 | compiling <acronym>CNI</acronym> code.  Note that you must also compile | 
|---|
| 552 | your C++ source code with <literal>-fno-rtti</literal>. | 
|---|
| 553 | </para> | 
|---|
| 554 | <para> | 
|---|
| 555 | Calling a Java instance method in <acronym>CNI</acronym> is done | 
|---|
| 556 | using the standard C++ syntax.  For example: | 
|---|
| 557 | <programlisting> | 
|---|
| 558 | java::lang::Number *x; | 
|---|
| 559 | if (x->doubleValue() > 0.0) ... | 
|---|
| 560 | </programlisting> | 
|---|
| 561 | </para> | 
|---|
| 562 | <para> | 
|---|
| 563 | Defining a Java native instance method is also done the natural way: | 
|---|
| 564 | <programlisting> | 
|---|
| 565 | #include <java/lang/Integer.h> | 
|---|
| 566 | jdouble | 
|---|
| 567 | java::lang:Integer::doubleValue() | 
|---|
| 568 | { | 
|---|
| 569 | return (jdouble) value; | 
|---|
| 570 | } | 
|---|
| 571 | </programlisting> | 
|---|
| 572 | </para> | 
|---|
| 573 | </sect2> | 
|---|
| 574 |  | 
|---|
| 575 | <sect2><title>Interface method calls</title> | 
|---|
| 576 | <para> | 
|---|
| 577 | In Java you can call a method using an interface reference. | 
|---|
| 578 | This is not yet supported in <acronym>CNI</acronym>.</para> | 
|---|
| 579 | </sect2> | 
|---|
| 580 | </sect1> | 
|---|
| 581 |  | 
|---|
| 582 | <sect1><title>Object allocation</title> | 
|---|
| 583 |  | 
|---|
| 584 | <para> | 
|---|
| 585 | New Java objects are allocated using a | 
|---|
| 586 | <firstterm>class-instance-creation-expression</firstterm>: | 
|---|
| 587 | <programlisting> | 
|---|
| 588 | new <replaceable>Type</replaceable> ( <replaceable>arguments</replaceable> ) | 
|---|
| 589 | </programlisting> | 
|---|
| 590 | The same syntax is used in C++.  The main difference is that | 
|---|
| 591 | C++ objects have to be explicitly deleted; in Java they are | 
|---|
| 592 | automatically deleted by the garbage collector. | 
|---|
| 593 | Using <acronym>CNI</acronym>, you can allocate a new object | 
|---|
| 594 | using standard C++ syntax.  The C++ compiler is smart enough to | 
|---|
| 595 | realize the class is a Java class, and hence it needs to allocate | 
|---|
| 596 | memory from the garbage collector.  If you have overloaded | 
|---|
| 597 | constructors, the compiler will choose the correct one | 
|---|
| 598 | using standard C++ overload resolution rules.  For example: | 
|---|
| 599 | <programlisting> | 
|---|
| 600 | java::util::Hashtable *ht = new java::util::Hashtable(120); | 
|---|
| 601 | </programlisting> | 
|---|
| 602 | </para> | 
|---|
| 603 | <para> | 
|---|
| 604 | <funcsynopsis> | 
|---|
| 605 | <funcdef>void *<function>_Jv_AllocBytes</function></funcdef> | 
|---|
| 606 | <paramdef>jsize <parameter>size</parameter></paramdef> | 
|---|
| 607 | </funcsynopsis> | 
|---|
| 608 | Allocate <parameter>size</parameter> bytes.  This memory is not | 
|---|
| 609 | scanned by the garbage collector.  However, it will be freed by | 
|---|
| 610 | the GC if no references to it are discovered. | 
|---|
| 611 | </para> | 
|---|
| 612 | </sect1> | 
|---|
| 613 |  | 
|---|
| 614 | <sect1><title>Interfaces</title> | 
|---|
| 615 | <para> | 
|---|
| 616 | A Java class can <firstterm>implement</firstterm> zero or more | 
|---|
| 617 | <firstterm>interfaces</firstterm>, in addition to inheriting from | 
|---|
| 618 | a single base class. | 
|---|
| 619 | An interface is a collection of constants and method specifications; | 
|---|
| 620 | it is similar to the <firstterm>signatures</firstterm> available | 
|---|
| 621 | as a G++ extension.  An interface provides a subset of the | 
|---|
| 622 | functionality of C++ abstract virtual base classes, but they | 
|---|
| 623 | are currently implemented differently. | 
|---|
| 624 | CNI does not currently provide any support for interfaces, | 
|---|
| 625 | or calling methods from an interface pointer. | 
|---|
| 626 | This is partly because we are planning to re-do how | 
|---|
| 627 | interfaces are implemented in <acronym>gcj</acronym>. | 
|---|
| 628 | </para> | 
|---|
| 629 | </sect1> | 
|---|
| 630 |  | 
|---|
| 631 | <sect1><title>Strings</title> | 
|---|
| 632 | <para> | 
|---|
| 633 | <acronym>CNI</acronym> provides a number of utility functions for | 
|---|
| 634 | working with Java <literal>String</literal> objects. | 
|---|
| 635 | The names and interfaces are analogous to those of <acronym>JNI</acronym>. | 
|---|
| 636 | </para> | 
|---|
| 637 |  | 
|---|
| 638 | <para> | 
|---|
| 639 | <funcsynopsis> | 
|---|
| 640 | <funcdef>jstring <function>JvNewString</function></funcdef> | 
|---|
| 641 | <paramdef>const jchar *<parameter>chars</parameter></paramdef> | 
|---|
| 642 | <paramdef>jsize <parameter>len</parameter></paramdef> | 
|---|
| 643 | </funcsynopsis> | 
|---|
| 644 | Creates a new Java String object, where | 
|---|
| 645 | <parameter>chars</parameter> are the contents, and | 
|---|
| 646 | <parameter>len</parameter> is the number of characters. | 
|---|
| 647 | </para> | 
|---|
| 648 |  | 
|---|
| 649 | <para> | 
|---|
| 650 | <funcsynopsis> | 
|---|
| 651 | <funcdef>jstring <function>JvNewStringLatin1</function></funcdef> | 
|---|
| 652 | <paramdef>const char *<parameter>bytes</parameter></paramdef> | 
|---|
| 653 | <paramdef>jsize <parameter>len</parameter></paramdef> | 
|---|
| 654 | </funcsynopsis> | 
|---|
| 655 | Creates a new Java String object, where <parameter>bytes</parameter> | 
|---|
| 656 | are the Latin-1 encoded | 
|---|
| 657 | characters, and <parameter>len</parameter> is the length of | 
|---|
| 658 | <parameter>bytes</parameter>, in bytes. | 
|---|
| 659 | </para> | 
|---|
| 660 |  | 
|---|
| 661 | <para> | 
|---|
| 662 | <funcsynopsis> | 
|---|
| 663 | <funcdef>jstring <function>JvNewStringLatin1</function></funcdef> | 
|---|
| 664 | <paramdef>const char *<parameter>bytes</parameter></paramdef> | 
|---|
| 665 | </funcsynopsis> | 
|---|
| 666 | Like the first JvNewStringLatin1, but computes <parameter>len</parameter> | 
|---|
| 667 | using <literal>strlen</literal>. | 
|---|
| 668 | </para> | 
|---|
| 669 |  | 
|---|
| 670 | <para> | 
|---|
| 671 | <funcsynopsis> | 
|---|
| 672 | <funcdef>jstring <function>JvNewStringUTF</function></funcdef> | 
|---|
| 673 | <paramdef>const char *<parameter>bytes</parameter></paramdef> | 
|---|
| 674 | </funcsynopsis> | 
|---|
| 675 | Creates a new Java String object, where <parameter>bytes</parameter> are | 
|---|
| 676 | the UTF-8 encoded characters of the string, terminated by a null byte. | 
|---|
| 677 | </para> | 
|---|
| 678 |  | 
|---|
| 679 | <para> | 
|---|
| 680 | <funcsynopsis> | 
|---|
| 681 | <funcdef>jchar *<function>JvGetStringChars</function></funcdef> | 
|---|
| 682 | <paramdef>jstring <parameter>str</parameter></paramdef> | 
|---|
| 683 | </funcsynopsis> | 
|---|
| 684 | Returns a pointer to the array of characters which make up a string. | 
|---|
| 685 | </para> | 
|---|
| 686 |  | 
|---|
| 687 | <para> | 
|---|
| 688 | <funcsynopsis> | 
|---|
| 689 | <funcdef> int <function>JvGetStringUTFLength</function></funcdef> | 
|---|
| 690 | <paramdef>jstring <parameter>str</parameter></paramdef> | 
|---|
| 691 | </funcsynopsis> | 
|---|
| 692 | Returns number of bytes required to encode contents | 
|---|
| 693 | of <parameter>str</parameter> as UTF-8. | 
|---|
| 694 | </para> | 
|---|
| 695 |  | 
|---|
| 696 | <para> | 
|---|
| 697 | <funcsynopsis> | 
|---|
| 698 | <funcdef> jsize <function>JvGetStringUTFRegion</function></funcdef> | 
|---|
| 699 | <paramdef>jstring <parameter>str</parameter></paramdef> | 
|---|
| 700 | <paramdef>jsize <parameter>start</parameter></paramdef> | 
|---|
| 701 | <paramdef>jsize <parameter>len</parameter></paramdef> | 
|---|
| 702 | <paramdef>char *<parameter>buf</parameter></paramdef> | 
|---|
| 703 | </funcsynopsis> | 
|---|
| 704 | This puts the UTF-8 encoding of a region of the | 
|---|
| 705 | string <parameter>str</parameter> into | 
|---|
| 706 | the buffer <parameter>buf</parameter>. | 
|---|
| 707 | The region of the string to fetch is specifued by | 
|---|
| 708 | <parameter>start</parameter> and <parameter>len</parameter>. | 
|---|
| 709 | It is assumed that <parameter>buf</parameter> is big enough | 
|---|
| 710 | to hold the result.  Note | 
|---|
| 711 | that <parameter>buf</parameter> is <emphasis>not</emphasis> null-terminated. | 
|---|
| 712 | </para> | 
|---|
| 713 | </sect1> | 
|---|
| 714 |  | 
|---|
| 715 | <sect1><title>Class Initialization</title> | 
|---|
| 716 | <para> | 
|---|
| 717 | Java requires that each class be automatically initialized at the time | 
|---|
| 718 | of the first active use.  Initializing a class involves | 
|---|
| 719 | initializing the static fields, running code in class initializer | 
|---|
| 720 | methods, and initializing base classes.  There may also be | 
|---|
| 721 | some implementation specific actions, such as allocating | 
|---|
| 722 | <classname>String</classname> objects corresponding to string literals in | 
|---|
| 723 | the code.</para> | 
|---|
| 724 | <para> | 
|---|
| 725 | The Gcj compiler inserts calls to <literal>JvInitClass</literal> (actually | 
|---|
| 726 | <literal>_Jv_InitClass</literal>) at appropriate places to ensure that a | 
|---|
| 727 | class is initialized when required.  The C++ compiler does not | 
|---|
| 728 | insert these calls automatically - it is the programmer's | 
|---|
| 729 | responsibility to make sure classes are initialized.  However, | 
|---|
| 730 | this is fairly painless because of the conventions assumed by the Java | 
|---|
| 731 | system.</para> | 
|---|
| 732 | <para> | 
|---|
| 733 | First, <literal>libgcj</literal> will make sure a class is initialized | 
|---|
| 734 | before an instance of that object is created.  This is one | 
|---|
| 735 | of the responsibilities of the <literal>new</literal> operation.  This is | 
|---|
| 736 | taken care of both in Java code, and in C++ code.  (When the G++ | 
|---|
| 737 | compiler sees a <literal>new</literal> of a Java class, it will call | 
|---|
| 738 | a routine in <literal>libgcj</literal> to allocate the object, and that | 
|---|
| 739 | routine will take care of initializing the class.)  It follows that you can | 
|---|
| 740 | access an instance field, or call an instance (non-static) | 
|---|
| 741 | method and be safe in the knowledge that the class and all | 
|---|
| 742 | of its base classes have been initialized.</para> | 
|---|
| 743 | <para> | 
|---|
| 744 | Invoking a static method is also safe.  This is because the | 
|---|
| 745 | Java compiler adds code to the start of a static method to make sure | 
|---|
| 746 | the class is initialized.  However, the C++ compiler does not | 
|---|
| 747 | add this extra code.  Hence, if you write a native static method | 
|---|
| 748 | using CNI, you are responsible for calling <literal>JvInitClass</literal> | 
|---|
| 749 | before doing anything else in the method (unless you are sure | 
|---|
| 750 | it is safe to leave it out).</para> | 
|---|
| 751 | <para> | 
|---|
| 752 | Accessing a static field also requires the class of the | 
|---|
| 753 | field to be initialized.  The Java compiler will generate code | 
|---|
| 754 | to call <literal>_Jv_InitClass</literal> before getting or setting the field. | 
|---|
| 755 | However, the C++ compiler will not generate this extra code, | 
|---|
| 756 | so it is your responsibility to make sure the class is | 
|---|
| 757 | initialized before you access a static field.</para> | 
|---|
| 758 | </sect1> | 
|---|
| 759 | <sect1><title>Exception Handling</title> | 
|---|
| 760 | <para> | 
|---|
| 761 | While C++ and Java share a common exception handling framework, | 
|---|
| 762 | things are not yet perfectly integrated.  The main issue is that the | 
|---|
| 763 | <quote>run-time type information</quote> facilities of the two | 
|---|
| 764 | languages are not integrated.</para> | 
|---|
| 765 | <para> | 
|---|
| 766 | Still, things work fairly well.  You can throw a Java exception from | 
|---|
| 767 | C++ using the ordinary <literal>throw</literal> construct, and this | 
|---|
| 768 | exception can be caught by Java code.  Similarly, you can catch an | 
|---|
| 769 | exception thrown from Java using the C++ <literal>catch</literal> | 
|---|
| 770 | construct. | 
|---|
| 771 | <para> | 
|---|
| 772 | Note that currently you cannot mix C++ catches and Java catches in | 
|---|
| 773 | a single C++ translation unit.  We do intend to fix this eventually. | 
|---|
| 774 | </para> | 
|---|
| 775 | <para> | 
|---|
| 776 | Here is an example: | 
|---|
| 777 | <programlisting> | 
|---|
| 778 | if (i >= count) | 
|---|
| 779 | throw new java::lang::IndexOutOfBoundsException(); | 
|---|
| 780 | </programlisting> | 
|---|
| 781 | </para> | 
|---|
| 782 | <para> | 
|---|
| 783 | Normally, GNU C++ will automatically detect when you are writing C++ | 
|---|
| 784 | code that uses Java exceptions, and handle them appropriately. | 
|---|
| 785 | However, if C++ code only needs to execute destructors when Java | 
|---|
| 786 | exceptions are thrown through it, GCC will guess incorrectly.  Sample | 
|---|
| 787 | problematic code: | 
|---|
| 788 | <programlisting> | 
|---|
| 789 | struct S { ~S(); }; | 
|---|
| 790 | extern void bar();    // is implemented in Java and may throw exceptions | 
|---|
| 791 | void foo() | 
|---|
| 792 | { | 
|---|
| 793 | S s; | 
|---|
| 794 | bar(); | 
|---|
| 795 | } | 
|---|
| 796 | </programlisting> | 
|---|
| 797 | The usual effect of an incorrect guess is a link failure, complaining of | 
|---|
| 798 | a missing routine called <literal>__gxx_personality_v0</literal>. | 
|---|
| 799 | </para> | 
|---|
| 800 | <para> | 
|---|
| 801 | You can inform the compiler that Java exceptions are to be used in a | 
|---|
| 802 | translation unit, irrespective of what it might think, by writing | 
|---|
| 803 | <literal>#pragma GCC java_exceptions</literal> at the head of the | 
|---|
| 804 | file.  This <literal>#pragma</literal> must appear before any | 
|---|
| 805 | functions that throw or catch exceptions, or run destructors when | 
|---|
| 806 | exceptions are thrown through them.</para> | 
|---|
| 807 | </sect1> | 
|---|
| 808 |  | 
|---|
| 809 | <sect1><title>Synchronization</title> | 
|---|
| 810 | <para> | 
|---|
| 811 | Each Java object has an implicit monitor. | 
|---|
| 812 | The Java VM uses the instruction <literal>monitorenter</literal> to acquire | 
|---|
| 813 | and lock a monitor, and <literal>monitorexit</literal> to release it. | 
|---|
| 814 | The JNI has corresponding methods <literal>MonitorEnter</literal> | 
|---|
| 815 | and <literal>MonitorExit</literal>.  The corresponding CNI macros | 
|---|
| 816 | are <literal>JvMonitorEnter</literal> and <literal>JvMonitorExit</literal>. | 
|---|
| 817 | </para> | 
|---|
| 818 | <para> | 
|---|
| 819 | The Java source language does not provide direct access to these primitives. | 
|---|
| 820 | Instead, there is a <literal>synchronized</literal> statement that does an | 
|---|
| 821 | implicit <literal>monitorenter</literal> before entry to the block, | 
|---|
| 822 | and does a <literal>monitorexit</literal> on exit from the block. | 
|---|
| 823 | Note that the lock has to be released even the block is abnormally | 
|---|
| 824 | terminated by an exception, which means there is an implicit | 
|---|
| 825 | <literal>try</literal>-<literal>finally</literal>. | 
|---|
| 826 | </para> | 
|---|
| 827 | <para> | 
|---|
| 828 | From C++, it makes sense to use a destructor to release a lock. | 
|---|
| 829 | CNI defines the following utility class. | 
|---|
| 830 | <programlisting> | 
|---|
| 831 | class JvSynchronize() { | 
|---|
| 832 | jobject obj; | 
|---|
| 833 | JvSynchronize(jobject o) { obj = o; JvMonitorEnter(o); } | 
|---|
| 834 | ~JvSynchronize() { JvMonitorExit(obj); } | 
|---|
| 835 | }; | 
|---|
| 836 | </programlisting> | 
|---|
| 837 | The equivalent of Java's: | 
|---|
| 838 | <programlisting> | 
|---|
| 839 | synchronized (OBJ) { CODE; } | 
|---|
| 840 | </programlisting> | 
|---|
| 841 | can be simply expressed: | 
|---|
| 842 | <programlisting> | 
|---|
| 843 | { JvSynchronize dummy(OBJ); CODE; } | 
|---|
| 844 | </programlisting> | 
|---|
| 845 | </para> | 
|---|
| 846 | <para> | 
|---|
| 847 | Java also has methods with the <literal>synchronized</literal> attribute. | 
|---|
| 848 | This is equivalent to wrapping the entire method body in a | 
|---|
| 849 | <literal>synchronized</literal> statement. | 
|---|
| 850 | (Alternatively, an implementation could require the caller to do | 
|---|
| 851 | the synchronization.  This is not practical for a compiler, because | 
|---|
| 852 | each virtual method call would have to test at run-time if | 
|---|
| 853 | synchronization is needed.)  Since in <literal>gcj</literal> | 
|---|
| 854 | the <literal>synchronized</literal> attribute is handled by the | 
|---|
| 855 | method implementation, it is up to the programmer | 
|---|
| 856 | of a synchronized native method to handle the synchronization | 
|---|
| 857 | (in the C++ implementation of the method). | 
|---|
| 858 | In otherwords, you need to manually add <literal>JvSynchronize</literal> | 
|---|
| 859 | in a <literal>native synchornized</literal> method.</para> | 
|---|
| 860 | </sect1> | 
|---|
| 861 |  | 
|---|
| 862 | <sect1><title>Reflection</title> | 
|---|
| 863 | <para>The types <literal>jfieldID</literal> and <literal>jmethodID</literal> | 
|---|
| 864 | are as in JNI.</para> | 
|---|
| 865 | <para> | 
|---|
| 866 | The function <literal>JvFromReflectedField</literal>, | 
|---|
| 867 | <literal>JvFromReflectedMethod</literal>, | 
|---|
| 868 | <literal>JvToReflectedField</literal>, and | 
|---|
| 869 | <literal>JvToFromReflectedMethod</literal> (as in Java 2 JNI) | 
|---|
| 870 | will be added shortly, as will other functions corresponding to JNI.</para> | 
|---|
| 871 |  | 
|---|
| 872 | <sect1><title>Using gcjh</title> | 
|---|
| 873 | <para> | 
|---|
| 874 | The <command>gcjh</command> is used to generate C++ header files from | 
|---|
| 875 | Java class files.  By default, <command>gcjh</command> generates | 
|---|
| 876 | a relatively straightforward C++ header file.  However, there | 
|---|
| 877 | are a few caveats to its use, and a few options which can be | 
|---|
| 878 | used to change how it operates: | 
|---|
| 879 | </para> | 
|---|
| 880 | <variablelist> | 
|---|
| 881 | <varlistentry> | 
|---|
| 882 | <term><literal>--classpath</literal> <replaceable>path</replaceable></term> | 
|---|
| 883 | <term><literal>--CLASSPATH</literal> <replaceable>path</replaceable></term> | 
|---|
| 884 | <term><literal>-I</literal> <replaceable>dir</replaceable></term> | 
|---|
| 885 | <listitem><para> | 
|---|
| 886 | These options can be used to set the class path for gcjh. | 
|---|
| 887 | Gcjh searches the class path the same way the compiler does; | 
|---|
| 888 | these options have their familiar meanings.</para> | 
|---|
| 889 | </listitem> | 
|---|
| 890 | </varlistentry> | 
|---|
| 891 |  | 
|---|
| 892 | <varlistentry> | 
|---|
| 893 | <term><literal>-d <replaceable>directory</replaceable></literal></term> | 
|---|
| 894 | <listitem><para> | 
|---|
| 895 | Puts the generated <literal>.h</literal> files | 
|---|
| 896 | beneath <replaceable>directory</replaceable>.</para> | 
|---|
| 897 | </listitem> | 
|---|
| 898 | </varlistentry> | 
|---|
| 899 |  | 
|---|
| 900 | <varlistentry> | 
|---|
| 901 | <term><literal>-o <replaceable>file</replaceable></literal></term> | 
|---|
| 902 | <listitem><para> | 
|---|
| 903 | Sets the name of the <literal>.h</literal> file to be generated. | 
|---|
| 904 | By default the <literal>.h</literal> file is named after the class. | 
|---|
| 905 | This option only really makes sense if just a single class file | 
|---|
| 906 | is specified.</para> | 
|---|
| 907 | </listitem> | 
|---|
| 908 | </varlistentry> | 
|---|
| 909 |  | 
|---|
| 910 | <varlistentry> | 
|---|
| 911 | <term><literal>--verbose</literal></term> | 
|---|
| 912 | <listitem><para> | 
|---|
| 913 | gcjh will print information to stderr as it works.</para> | 
|---|
| 914 | </listitem> | 
|---|
| 915 | </varlistentry> | 
|---|
| 916 |  | 
|---|
| 917 | <varlistentry> | 
|---|
| 918 | <term><literal>-M</literal></term> | 
|---|
| 919 | <term><literal>-MM</literal></term> | 
|---|
| 920 | <term><literal>-MD</literal></term> | 
|---|
| 921 | <term><literal>-MMD</literal></term> | 
|---|
| 922 | <listitem><para> | 
|---|
| 923 | These options can be used to generate dependency information | 
|---|
| 924 | for the generated header file.  They work the same way as the | 
|---|
| 925 | corresponding compiler options.</para> | 
|---|
| 926 | </listitem> | 
|---|
| 927 | </varlistentry> | 
|---|
| 928 |  | 
|---|
| 929 | <varlistentry> | 
|---|
| 930 | <term><literal>-prepend <replaceable>text</replaceable></literal></term> | 
|---|
| 931 | <listitem><para> | 
|---|
| 932 | This causes the <replaceable>text</replaceable> to be put into the generated | 
|---|
| 933 | header just after class declarations (but before declaration | 
|---|
| 934 | of the current class).  This option should be used with caution.</para> | 
|---|
| 935 | </listitem> | 
|---|
| 936 | </varlistentry> | 
|---|
| 937 |  | 
|---|
| 938 | <varlistentry> | 
|---|
| 939 | <term><literal>-friend <replaceable>text</replaceable></literal></term> | 
|---|
| 940 | <listitem><para> | 
|---|
| 941 | This causes the <replaceable>text</replaceable> to be put into the class | 
|---|
| 942 | declaration after a <literal>friend</literal> keyword. | 
|---|
| 943 | This can be used to declare some | 
|---|
| 944 | other class or function to be a friend of this class. | 
|---|
| 945 | This option should be used with caution.</para> | 
|---|
| 946 | </listitem> | 
|---|
| 947 | </varlistentry> | 
|---|
| 948 |  | 
|---|
| 949 | <varlistentry> | 
|---|
| 950 | <term><literal>-add <replaceable>text</replaceable></literal></term> | 
|---|
| 951 | <listitem><para> | 
|---|
| 952 | The <replaceable>text</replaceable> is inserted into the class declaration. | 
|---|
| 953 | This option should be used with caution.</para> | 
|---|
| 954 | </listitem> | 
|---|
| 955 | </varlistentry> | 
|---|
| 956 |  | 
|---|
| 957 | <varlistentry> | 
|---|
| 958 | <term><literal>-append <replaceable>text</replaceable></literal></term> | 
|---|
| 959 | <listitem><para> | 
|---|
| 960 | The <replaceable>text</replaceable> is inserted into the header file | 
|---|
| 961 | after the class declaration.  One use for this is to generate | 
|---|
| 962 | inline functions.  This option should be used with caution. | 
|---|
| 963 | </listitem> | 
|---|
| 964 | </varlistentry> | 
|---|
| 965 | </variablelist> | 
|---|
| 966 | <para> | 
|---|
| 967 | All other options not beginning with a <literal>-</literal> are treated | 
|---|
| 968 | as the names of classes for which headers should be generated.</para> | 
|---|
| 969 | <para> | 
|---|
| 970 | gcjh will generate all the required namespace declarations and | 
|---|
| 971 | <literal>#include</literal>'s for the header file. | 
|---|
| 972 | In some situations, gcjh will generate simple inline member | 
|---|
| 973 | functions.  Note that, while gcjh puts <literal>#pragma | 
|---|
| 974 | interface</literal> in the generated header file, you should | 
|---|
| 975 | <emphasis>not</emphasis> put <literal>#pragma implementation</literal> | 
|---|
| 976 | into your C++ source file.  If you do, duplicate definitions of | 
|---|
| 977 | inline functions will sometimes be created, leading to link-time | 
|---|
| 978 | errors. | 
|---|
| 979 | </para> | 
|---|
| 980 | <para> | 
|---|
| 981 | There are a few cases where gcjh will fail to work properly:</para> | 
|---|
| 982 | <para> | 
|---|
| 983 | gcjh assumes that all the methods and fields of a class have ASCII | 
|---|
| 984 | names.  The C++ compiler cannot correctly handle non-ASCII | 
|---|
| 985 | identifiers.  gcjh does not currently diagnose this problem.</para> | 
|---|
| 986 | <para> | 
|---|
| 987 | gcjh also cannot fully handle classes where a field and a method have | 
|---|
| 988 | the same name.  If the field is static, an error will result. | 
|---|
| 989 | Otherwise, the field will be renamed in the generated header; `__' | 
|---|
| 990 | will be appended to the field name.</para> | 
|---|
| 991 | <para> | 
|---|
| 992 | Eventually we hope to change the C++ compiler so that these | 
|---|
| 993 | restrictions can be lifted.</para> | 
|---|
| 994 | </sect1> | 
|---|
| 995 |  | 
|---|
| 996 | </article> | 
|---|