199
502
JAVA_INCLUDE = -ID:\jdk1.3\include -ID:\jdk1.3\include\win32
202
swig -java -shadow -o $(WRAPFILE) $(INTERFACE)
505
swig -java -o $(WRAPFILE) $(INTERFACE)
203
506
$(CC) $(CFLAGS) $(JAVA_INCLUDE) $(SRCS) $(WRAPFILE)
204
507
set LIB=$(TOOLS)\lib
205
508
$(LINK) $(LOPT) -out:example.dll $(LIBS) example.obj example_wrap.obj
207
510
</pre></blockquote>
209
To build the extension, run NMAKE (you may need to run <tt>vcvars32</tt> first). This is a pretty simplistic Makefile, but hopefully its enough to get you started. <p>
211
<a name="n3"></a><h2>The low-level Java/C interface</h2>
212
The SWIG Java module is based upon a basic low-level interface that provides access to C functions, variables, constants, and C++ classes. This low-level interface is not the recommended way to use SWIG with Java; shadow classes are the recommended way. This low-level interface is used by the shadow class interface so it is used behind the scenes.<p>
214
<a name="n108"></a><h3> Modules and the module class</h3>
215
The SWIG <tt>%module</tt> directive specifies the name of the Java module. If you specified `<tt>%module example</tt>', then everything found in a SWIG interface file will be contained within the Java module class which in this case will be called `<tt>example</tt>'. In other words the module class contains all the C/C++ functions and accessor functions to variables that have been wrapped by SWIG. Make sure you don't use the same name as a Java keyword for your module name else the Java output will not compile.<p>
217
<a name="n109"></a><h3> Functions</h3>
218
C/C++ functions are mapped directly into a matching method in a Java class named after the module name. For example :<p>
223
extern int fact(int n);
225
Will produce the following JNI c function:
227
JNIEXPORT jint JNICALL Java_example_fact(JNIEnv *jenv, jclass jcls, jint jarg0) {
229
This will in turn call the desired <tt>fact</tt> function. The JNI naming mangling isn't pretty, but you can see from the above that the native function call is expecting a class 'example'. SWIG outputs the JNI Java code into the example class:
231
public class example {
232
public final static native int fact(int jarg0);
512
To build the DLL and compile the java code, run NMAKE (you may need to run <tt>vcvars32</tt> first).
513
This is a pretty simplistic Makefile, but hopefully its enough to get you started.
514
Of course you may want to make changes for it to work for C++ by adding in the -c++ command line switch for swig and replacing .c with .cxx.
518
<a name="java_basic_tour"></a>
519
<a name="n14"></a><H2>17.3 A tour of basic C/C++ wrapping</H2>
522
By default, SWIG attempts to build a natural Java interface
523
to your C/C++ code. Functions are wrapped as functions, classes are wrapped as classes,
524
variables are wrapped with JavaBean type getters and setters and so forth.
525
This section briefly covers the essential aspects of this wrapping.
527
<a name="module_packages_classes"></a>
528
<a name="n15"></a><H3>17.3.1 Modules, packages and generated Java classes</H3>
531
The SWIG <tt>%module</tt> directive specifies the name of the Java
532
module. When you specify `<tt>%module example</tt>', the <i>module name</i>
533
determines the name of some of the generated files in the module.
534
The generated code consists of a <i>module class</i> file <tt>example.java</tt>, an
535
<i>intermediary JNI class</i> file, <tt>exampleJNI.java</tt> as well as numerous other Java <i>proxy class</i> files.
536
Each proxy class is named after the structs, unions and classes you are wrapping.
537
You may also get a <i>constants interface</i> file if you are wrapping any enumerations or constants, for example <tt>exampleConstants.java</tt>.
538
When choosing a module name, make sure you don't use the same name as one of the generated
539
proxy class files nor a Java keyword. Sometimes a C/C++ type cannot be wrapped by a proxy class, for
540
example a pointer to a primitive type. In these situations a <i>type wrapper class</i> is generated.
541
Details of all these generated classes will unfold as you read this section.
544
The JNI (C/C++) code is generated into a file which also contains the module name, for example <tt>example_wrap.cxx</tt>
545
or </tt>example_wrap.c</tt>. These C or C++ files complete the contents of the module.
548
The generated Java classes can be placed into a Java package by using the <tt>-package</tt> commandline option.
549
This is often combined with the <tt>-outdir</tt> to specify a package directory for generating the Java files.
552
swig -java -package com.bloggs.swig -outdir com/bloggs/swig example.i
555
SWIG won't create the directory, so make sure it exists beforehand.
557
<a name="functions"></a>
558
<a name="n16"></a><H3>17.3.2 Functions</H3>
561
There is no such thing as a global Java function so global C functions are wrapped as static methods in
562
the module class. For example,
565
<blockquote><pre>%module example
570
creates a static function that works exactly like you think it might:<p>
573
public class example {
574
public static int fact(int n) {
575
// makes call using JNI to the C function
234
578
</pre></blockquote>
236
It can be used as follows from Java:<p>
582
The Java class <tt>example</tt> is the <i>module class</i>. The function can be used as follows from Java:<p>
238
584
<blockquote><pre>
239
585
System.out.println(example.fact(4));
240
586
</pre></blockquote>
242
<a name="n110"></a><h3> Variable Linking</h3>
243
SWIG provides access to C/C++ global variables through the class named after the module name, in other words all global variables are wrapped into the module class. Java does not allow the overriding of the dot operator so all variables are accessed through getters and setters. For example: <p>
589
<a name="global_variables"></a>
590
<a name="n17"></a><H3>17.3.3 Global variables</H3>
593
C/C++ global variables are fully supported by SWIG.
594
Java does not allow the overriding of the dot operator so all variables are accessed through getters and setters.
595
Again because there is no such thing as a
596
Java global variable, access to C/C++ global variables is done through static getter and setter functions in the module class.
244
598
<blockquote><pre>
245
/* SWIG interface file with global variables */
599
// SWIG interface file with global variables
248
602
extern int My_variable;
603
extern double density;
250
605
</pre></blockquote>
255
// Print out the value of a c global variable
256
System.out.println("My Variable = " + example.get_My_variable());
258
//Set the value of a C global variable
259
example.set_My_variable(100);
261
The value returned by the getter will always be up to date even if the value is changed in c. The setter will not be generated if the variable is a c 'const'.<p>
263
<a name="n111"></a><h3> Enums</h3>
264
SWIG will wrap enumerations. They appear as public final static Java variables. The Java enum names match the C/C++ enum names. For example, the following C enum:<p>
266
enum color { RED, BLUE, GREEN };
269
will be wrapped with the following Java:
271
public class example {
272
... maybe some other functions ...
273
public final static native int get_RED();
274
public final static native int get_BLUE();
275
public final static native int get_GREEN();
276
// enums and constants
277
public final static int RED = get_RED();
278
public final static int BLUE = get_BLUE();
279
public final static int GREEN = get_GREEN();
283
<a name="n112"></a><h3> Constants</h3>
284
C/C++ constants (from a #define) are wrapped by public final static Java variables. These constants are given the same name as the corresponding C constant. For example, the following C:<p>
287
#define FCONST 2.1828
289
#define SCONST "Hello World"
291
will be wrapped with the following Java:
293
public final static int ICONST = 42;
294
public final static double FCONST = 2.1828;
295
public final static String CCONST = "x";
296
public final static String SCONST = "Hello World";
299
<a name="n113"></a><h3> Pointers</h3>
300
All c pointers are treated as Java longs in the low-level interface. For example:<p>
302
int* pointer_fn(short* a, int* b, long* c);
304
will produce the following Java function:
306
public final static native long pointer_fn(long jarg0, long jarg1, long jarg2);
308
Unlike other language modules, no SWIG pointer library exists yet for the Java module. Until this is written it does restrict the functions that can be usefully used from Java. In the above <tt>pointer_fn</tt>, any long representing a c pointer can be passed to other c functions, but any value that the pointer points to cannot be accessed from Java without writing and using some accessor functions, for example:<p>
310
/* c accessor function for reading return values that are int pointers */
311
int getIntValue(int *ptr) {return *ptr;};
315
The return value can then be read from Java, for example:
317
long integerPtr = example.pointer_fn();
318
System.out.println("return value=" + example.getIntValue(integerPtr));
321
Pointers that are returned in one of the parameter arguments are more difficult and other workarounds are necessary. One method is to write a c function which returns the desired value after calling the appropriate function. However, as the section on shadow classes demonstrates, the situation is a lot better when using shadow classes.
324
Another alternative is to use the typemaps.i library. This file has examples to demonstrate, but essentially if you use the typemaps in this library you can use real values from Java where a pointer is required in c. When the pointer is an output from the c function, a Java array is used. The value that the pointer is pointing to is placed into the array which can be read by the calling function.
327
<a name="n114"></a><h3> Structures </h3>
328
The low-level SWIG interface only provides a simple interface to C structures. For example :<p>
613
// Print out value of a C global variable
614
System.out.println("My_variable = " + example.getMy_variable());
615
// Set the value of a C global variable
616
example.setDensity(0.8442);
619
The value returned by the getter will always be up to date even if the value is changed in C.
620
Note that the getters and setters produced follow the JavaBean property design pattern.
621
That is the first letter of the variable name is capitalized and preceded with set or get.
622
If you have the misfortune of wrapping two variables that differ only in the capitalization of their first letters,
623
use %rename to change one of the variable names. For example:
626
%rename Clash RenamedClash;
632
If a variable is declared as <tt>const</tt>, it is wrapped as a read-only variable.
633
That is only a getter is produced.
636
To make ordinary variables read-only, you can use the <tt>%immutable</tt> directive. For example:
646
The <tt>%immutable</tt> directive stays in effect until it is explicitly disabled using
650
If you just want to make a specific variable immutable, supply a declaration name. For example:
656
extern char *path; // Read-only (due to %immutable)
661
<a name="constants"></a>
662
<a name="n18"></a><H3>17.3.4 Constants</H3>
665
C/C++ constants are wrapped as Java static final variables.
666
To create a constant, use <tt>#define</tt> or the
667
<tt>%constant</tt> directive. For example:
672
#define VERSION "1.0"
673
%constant int FOO = 42;
674
%constant const char *path = "/usr/local";
678
By default the generated static final variables are initialised by making a JNI call to get their value.
679
The constants are generated into the constants interface and look like this:
682
public interface exampleConstants {
683
// enums and constants
684
public final static double PI = exampleJNI.get_PI();
685
public final static String VERSION = exampleJNI.get_VERSION();
686
public final static int FOO = exampleJNI.get_FOO();
687
public final static String path = exampleJNI.get_path();
691
These are runtime constants. They are not compiler constants that can, for example, be used
692
in a switch statement. This can be changed by using the <tt>%javaconst(flag)</tt> directive. It works like all
693
the other <a href="Customization.html#features">%feature directives</a>. The default is <tt>%javaconst(0)</tt>.
694
It is possible to initialize all wrapped constants from pure Java code by placing a <tt>%javaconst(1)</tt> <b>before</b> SWIG parses the constants.
695
Putting it at the top of your interface file would ensure this.
702
#define EXPRESSION (0x100+5)
708
public interface exampleConstants {
709
// enums and constants
710
public final static long BIG = exampleJNI.get_BIG();
711
public final static int EXPRESSION = (0x100+5);
715
Be careful using the <tt>%javaconst(1)</tt> directive as not all C code will compile as Java code. For example the
716
<tt>1000LL</tt> value for the <tt>BIG</tt> constant above would not generate valid Java code.
717
The example demonstrates how you can target particular constants (<tt>BIG</tt>) with <tt>%javaconst</tt>.
720
Note: declarations declared as <tt>const</tt> are wrapped as read-only variables and
721
will be accessed using a getter as described in the previous section. They
722
are not wrapped as constants.
725
<b>Compatibility Note:</b> In SWIG-1.3.19 and earlier releases, the constants were generated into the module class and the constants interface didn't exist.
726
Backwards compatibility is maintained as the module class implements the constants interface (even though some consider this type of interface implementation to be bad practice):
728
public class example implements exampleConstants {
732
You thus have the choice of accessing these constants from either the module class or the constants interface, for example,
733
<tt>example.EXPRESSION</tt> or <tt>exampleConstants.EXPRESSION</tt>.
736
<a name="enumerations"></a>
737
<a name="n19"></a><H3>17.3.5 Enumerations</H3>
740
Enumerations are wrapped as final static integers in Java and are also initialised using a JNI call. For example:
744
enum Beverage { ALE, LAGER=10, STOUT, PILSNER };
748
is wrapped into the constants interface, in a similar manner as constants (see previous section):
751
public interface exampleConstants {
752
// enums and constants
753
public final static int ALE = exampleJNI.get_ALE();
754
public final static int LAGER = exampleJNI.get_LAGER();
755
public final static int STOUT = exampleJNI.get_STOUT();
756
public final static int PILSNER = exampleJNI.get_PILSNER();
760
The <tt>%javaconst(flag)</tt> directive introduced in the previous section on constants can also be used with enums,
761
thereby also allowing enum values to be used in Java switch statements.
762
As is the case for constants, the default is <tt>%javaconst(0)</tt> as not all C values will compile as Java code.
763
However, it is recommended to add in a <tt>%javaconst(1)</tt> directive at the top of your
764
interface file as it is only on very rare occasions that this will produce code that won't compile under Java.
770
%javaconst(0) PILSNER;
771
enum Beverage { ALE, LAGER=10, STOUT, PILSNER };
778
public interface exampleConstants {
779
// enums and constants
780
public final static int ALE = 0;
781
public final static int LAGER = 10;
782
public final static int STOUT = LAGER+1;
783
public final static int PILSNER = exampleJNI.get_PILSNER();
787
As in the case of constants, you can access them through either the module class or the constants interface, for example, <tt>example.ALE</tt> or <tt>exampleConstants.ALE</tt>.
790
For enums, make sure that the definition of the enumeration actually appears in a header
791
file or in the wrapper file somehow---if you just have an enum in a SWIG interface without
792
also telling the C compiler about it, the wrapper code won't compile.
796
<a name="pointers"></a>
797
<a name="n20"></a><H3>17.3.6 Pointers</H3>
800
C/C++ pointers are fully supported by SWIG. Furthermore, SWIG has no problem working with
801
incomplete type information. Here is a rather simple interface:
807
FILE *fopen(const char *filename, const char *mode);
808
int fputs(const char *, FILE *);
813
When wrapped, you will be able to use the functions in a natural way from Java. For example:
817
SWIGTYPE_p_FILE f = example.fopen("junk","w");
818
example.fputs("Hello World\n", f);
823
C pointers in the Java module are stored in a Java <tt>long</tt> and cross the JNI boundary held within this 64 bit number.
824
Many other SWIG language modules use an encoding of the pointer in a string.
825
These scripting languages use the SWIG runtime type checker for dynamic type checking as they do not support static type checking by a compiler.
826
In order to implement static type checking of pointers within Java, they are wrapped by a simple Java class.
827
In the example above the <tt>FILE *</tt> pointer is wrapped with a <i>type wrapper class </i>
828
called <tt>SWIGTYPE_p_FILE</tt>.
831
Once obtained, a type wrapper object can be freely passed around to different C functions that
832
expect to receive an object of that type. The only thing you can't do is
833
dereference the pointer from Java. Of course, that isn't much of a concern in this example.
836
As much as you might be inclined to modify a pointer value directly
837
from Java, don't. The value is not necessarily the
838
same as the logical memory address of the underlying object. The value will
839
vary depending on the native byte-ordering of the platform (i.e.,
840
big-endian vs. little-endian).
841
Most JVMs are 32 bit applications so any JNI code must also be compiled as 32 bit.
842
The net result is pointers in JNI code are also 32 bits and
843
are stored in the high order 4 bytes on big-endian machines and in the low order 4 bytes on little-endian machines.
844
By design it is also not possible to manually cast
845
a pointer to a new type by using Java casts as it is particularly dangerous especially when
846
casting C++ objects. If you need to cast a pointer or
847
change its value, consider writing some helper functions instead. For
854
Bar *FooToBar(Foo *f) {
859
Foo *BarToFoo(Bar *b) {
860
return dynamic_cast<Foo*>(b);
863
Foo *IncrFoo(Foo *f, int i) {
870
Also, if working with C++, you should always try
871
to use the new C++ style casts. For example, in the above code, the
872
C-style cast may return a bogus result whereas as the C++-style cast will return
873
a NULL pointer if the conversion can't be performed.
876
<a name="structures"></a>
877
<a name="n21"></a><H3>17.3.7 Structures</H3>
880
If you wrap a C structure, it is wrapped by a Java class with getters and setters for access to the
881
member variables. For example,
330
884
<blockquote><pre>struct Vector {
334
888
</pre></blockquote>
335
This will be wrapped using native Java functions, where the first argument holds the pointer to an instance of the Vector struct. Example assuming the module name is 'example':
337
public class example {
338
public final static native void set_Vector_x(long jarg0, double jarg1);
339
public final static native double get_Vector_x(long jarg0);
340
public final static native void set_Vector_y(long jarg0, double jarg1);
341
public final static native double get_Vector_y(long jarg0);
342
public final static native void set_Vector_z(long jarg0, double jarg1);
343
public final static native double get_Vector_z(long jarg0);
346
These functions are then used in the resulting Java interface. For example:<p>
349
// v is a long holding the c pointer to a Vector that got created somehow
350
example.set_Vector_x(v, 7.8);
351
System.out.println("x=" + example.get_Vector_x(v));
353
When executed will display:<br>
358
Similar access is provided for unions and the data members of C++ classes.<p>
359
<a name="n115"></a><h3> C++ Classes</h3>
360
C++ classes are handled by building a set of low level accessor functions. Consider the following class :<p>
893
Vector v = new Vector();
899
The variable setters and getters are also based on the JavaBean design pattern already covered under the Global variables section.
900
Similar access is provided for unions and the public data members of C++ classes.<p>
902
This object is actually an instance of a Java class that has been wrapped around a pointer to the C structure.
903
This instance doesn't actually do anything--it just serves as a proxy.
904
The pointer to the C object is held in the Java proxy class in much the same way as pointers are held by type wrapper classes.
905
Further details about Java proxy classes are covered a little later.
908
<tt>const</tt> members of a structure are read-only. Data members
909
can also be forced to be read-only using the <tt>%immutable</tt> directive. For example:
916
int x; /* Read-only members */
925
When <tt>char *</tt> members of a structure are wrapped, the contents are assumed to be
926
dynamically allocated using <tt>malloc</tt> or <tt>new</tt> (depending on whether or not
927
SWIG is run with the -c++ option). When the structure member is set, the old contents will be
928
released and a new value created. If this is not the behavior you want, you will have to use
929
a typemap (described later).
932
If a structure contains arrays, access to those arrays is managed through pointers. For
933
example, consider this:
943
If accessed in Java, you will see behavior like this:
948
SWIGTYPE_p_int x = b.getX();
952
This pointer can be passed around to functions that expect to receive
953
an <tt>int *</tt> (just like C). You can also set the value of an array member using
954
another pointer. For example:
959
SWIGTYPE_p_int x = b.getX();
961
c.setX(x); // Copy contents of b.x to c.x
965
For array assignment (setters not getters), SWIG copies the entire contents of the array starting with the data pointed
966
to by <tt>b.x</tt>. In this example, 16 integers would be copied. Like C, SWIG makes
967
no assumptions about bounds checking---if you pass a bad pointer, you may get a segmentation
968
fault or access violation.
969
Array access can be changed from this default to use Java arrays and this is covered later.
972
When a member of a structure is itself a structure, it is handled as a
973
pointer. For example, suppose you have two structures like this:
987
Now, suppose that you access the <tt>f</tt> member of <tt>Bar</tt> like this:
996
In this case, <tt>x</tt> is a pointer that points to the <tt>Foo</tt> that is inside <tt>b</tt>.
997
This is the same value as generated by this C code:
1002
Foo *x = &b->f; /* Points inside b */
1006
Because the pointer points inside the structure, you can modify the contents and
1007
everything works just like you would expect. For example:
1012
b.getF().setA(3); // Modify b.f.a
1014
x.setA(3); // Modify x.a - this is the same as b.f.a
1019
<a name="classes"></a>
1020
<a name="n22"></a><H3>17.3.8 C++ classes</H3>
1023
C++ classes are wrapped by Java classes as well. For example, if you have this class,
362
1026
<blockquote><pre>class List {
368
1032
void remove(char *item);
369
1033
char *get(int n);
371
static void print(List *l);
373
1036
</pre></blockquote>
375
When wrapped by SWIG, will produce the following JNI c code to access the class (assuming the module is set to 'example'):<p>
378
JNIEXPORT jlong JNICALL Java_example_new_1List(JNIEnv *jenv, jclass jcls);
379
JNIEXPORT void JNICALL Java_example_delete_1List(JNIEnv *jenv, jclass jcls, jlong jarg0);
380
JNIEXPORT jint JNICALL Java_example_List_1search(JNIEnv *jenv, jclass jcls, jlong jarg0, jstring jarg1);
381
JNIEXPORT void JNICALL Java_example_List_1insert(JNIEnv *jenv, jclass jcls, jlong jarg0, jstring jarg1);
382
JNIEXPORT void JNICALL Java_example_List_1remove(JNIEnv *jenv, jclass jcls, jlong jarg0, jstring jarg1);
383
JNIEXPORT jstring JNICALL Java_example_List_1get(JNIEnv *jenv, jclass jcls, jlong jarg0, jint jarg1);
384
JNIEXPORT void JNICALL Java_example_set_1List_1length(JNIEnv *jenv, jclass jcls, jlong jarg0, jint jarg1);
385
JNIEXPORT jint JNICALL Java_example_get_1List_1length(JNIEnv *jenv, jclass jcls, jlong jarg0);
386
JNIEXPORT void JNICALL Java_example_List_1print(JNIEnv *jenv, jclass jcls, jlong jarg0);
388
where jarg0 is the 'this' pointer in non-static functions. The JNI specification requires a c interface.
390
The following JNI Java functions are also produced for access from Java:
392
public class example {
393
public final static native long new_List();
394
public final static native void delete_List(long jarg0);
395
public final static native int List_search(long jarg0, String jarg1);
396
public final static native void List_insert(long jarg0, String jarg1);
397
public final static native void List_remove(long jarg0, String jarg1);
398
public final static native String List_get(long jarg0, int jarg1);
399
public final static native void List_length_set(long jarg0, int jarg1);
400
public final static native int List_length_get(long jarg0);
401
public final static native void List_print(long jarg0);
405
From Java, these functions can be used to access the C++ class:<p>
407
long l = example.new_List();
408
example.List_insert(l,"Ale");
409
example.List_insert(l,"Stout");
410
example.List_insert(l,"Lager");
411
example.List_print(l);
412
int len = example.get_List_length(l);
413
System.out.println(len);
415
When executed might display:
424
While somewhat primitive, the low-level SWIG interface provides direct and flexible access to C++ objects. As it turns out, a more elegant method of accessing structures and classes is available using shadow classes.<p>
426
<a name="n4"></a><h2>Java shadow classes</h2>
427
The low-level interface generated by SWIG provides access to C structures and C++ classes, but it doesn't look much like a class that might be created in Java. However, it is possible to indirectly use the low-level C interface to write a Java class that looks like the original C++ class. In this case, the Java class is said to "shadow" the C++ class. That is, it behaves like the original class, but is really just a wrapper around a C++ class. The Java class is sometimes called a proxy class.<p>
428
<a name="n116"></a><h3> A simple example</h3>
429
For our earlier List class, a Java shadow class could be written by hand like this :<p>
433
protected long _cPtr;
434
protected boolean _cMemOwn;
436
public long getCPtr() {
441
_cPtr = example.new_List();
445
protected void finalize() {
449
public void _delete() {
450
if(_cPtr!=0 && _cMemOwn) {
451
example.delete_List(_cPtr);
456
public int search(String item) {
457
return example.List_search(_cPtr, item);
460
public void insert(String item) {
461
example.List_insert(_cPtr, item);
464
public void remove(String item) {
465
example.List_remove(_cPtr, item);
468
public String get(int n) {
469
return example.List_get(_cPtr, n);
472
public void setLength(int value) {
473
example.set_List_length(_cPtr, value);
476
public int getLength() {
477
return example.get_List_length(_cPtr);
480
public static void print(List l) {
481
example.List_print(l.getCPtr());
486
Which is roughly what SWIG outputs.
487
When used in Java, we can use the class as follows:<p>
1038
you can use it in Java like this:
489
1040
<blockquote><pre>
490
1041
List l = new List();
491
1042
l.insert("Ale");
492
1043
l.insert("Stout");
493
1044
l.insert("Lager");
495
int len = l.getLength();
496
System.out.println(len);
499
Obviously, this is a much nicer interface than before, it only required a small amount of Java coding, it is type-safe and fits in with the Java programming paradigm.<p>
501
<a name="n117"></a><h3> Why write shadow classes in Java?</h3>
502
While one could wrap C/C++ objects directly into Java as new Java types, this approach has a number of problems. First, as the C/C++ code gets complicated, the resulting wrapper code starts to become extremely ugly.<p>
504
By writing shadow classes in Java instead of C, the classes become real Java classes that can be easily used as base-classes in an inheritance hierarchy or for other applications. Writing the shadow classes in Java also greatly simplies coding complexity as writing them in Java is much easier than trying to accomplish the same thing in C. Finally, by writing shadow classes in Java, they are easy to modify and can be changed without ever recompiling any of the C code. The downside to using shadow classes over the simple interface is a slight performance degradation--a concern for some users.<p>
506
<a name="n118"></a><h3> Automated shadow class generation</h3>
507
SWIG automatically generates shadow classes when you use the <tt>-shadow</tt> option:<p>
509
<blockquote><pre>swig -java -shadow interface.i
512
This will create the following files:<p>
518
plus other .java files corresponding to each shadow class
522
The file <tt>interface_wrap.c</tt> contains the normal SWIG C JNI wrappers. The file <tt>interface.java</tt> contains the Java code corresponding to the Java native functions. The name of this file will be the same as specified by the <tt>%module</tt> directive in the SWIG interface file. These two files are produced whether or not the -shadow option is passed to SWIG. There will then be a <tt>.java</tt> file for each shadow class when -shadow is used. Note that if -c++ is passed to SWIG for wrapping C++ code, then a <tt>interface_wrap.cxx</tt> file replaces the <tt>interface_wrap.c</tt> file.
525
<a name="n119"></a><h3> Compiling modules with shadow classes</h3>
526
No changes need to be made to the compilation process when using shadow classes.<p>
528
<a name="n120"></a><h3> Where to go for more information</h3>
529
Shadow classes turn out to be so useful that they are used almost all of the time with SWIG. All of the examples presented here will assume that shadow classes have been enabled. The precise implementation of shadow classes is described at the end of this chapter.<p>
531
<a name="n5"></a><h2>Examples</h2>
533
The directory Examples/java has a number of examples. Looking at these is a good way to learn how the SWIG Java extension works. The Examples/index.html in the parent direcory contains the SWIG Examples Documentation and is a useful starting point. The following sections also describe plenty of examples.
535
<a name="n6"></a><h2>Exception handling </h2>
536
The SWIG <tt>%exception</tt> directive can be used to create a user-definable exception handler which can be used to convert errors in your C/C++ program into Java exceptions. The chapter on exception handling contains more details, but suppose you have a C++ class like the following:<p>
538
class RangeError {}; // Used for an exception
545
// Create a new array of fixed size
546
DoubleArray(int size) {
547
ptr = new double[size];
554
// Return the length of the array
559
// Get an item from the array and perform bounds checking.
560
double getitem(int i) {
561
if ((i >= 0) && (i < n))
567
// Set an item in the array and perform bounds checking.
568
void setitem(int i, double val) {
569
if ((i >= 0) && (i < n))
1045
String item = l.get(2);
1046
int length = l.getLength();
1049
Class data members are accessed in the same manner as C structures.
1052
Static class members are unsurprisingly wrapped as static members of the Java class:
1064
The static members work like any other Java static member:
1069
int bar = Spam.getBar();
1074
<a name="inheritance"></a>
1075
<a name="n23"></a><H3>17.3.9 C++ inheritance</H3>
1078
SWIG is fully aware of issues related to C++ inheritance. Therefore, if you have
1087
class Bar : public Foo {
1093
those classes are wrapped into a hierarchy of Java classes that reflect the same inheritance
1099
Class c = b.getClass();
1100
System.out.println(c.getSuperclass().getName());
1104
will of course display:
1111
Furthermore, if you have functions like this
1119
then the Java function <tt>spam()</tt> accepts instances of <tt>Foo</tt> or instances of any other proxy classes derived from <tt>Foo</tt>.
1122
Note that Java does not support multiple inheritance so any multiple inheritance in the C++ code is not going to work.
1123
A warning is given when multiple inheritance is detected and only the first base class is used.
1125
<a name="pointers_refs_arrays"></a>
1126
<a name="n24"></a><H3>17.3.10 Pointers, references, arrays and pass by value</H3>
1129
In C++, there are many different ways a function might receive
1130
and manipulate objects. For example:
1134
void spam1(Foo *x); // Pass by pointer
1135
void spam2(Foo &x); // Pass by reference
1136
void spam3(Foo x); // Pass by value
1137
void spam4(Foo x[]); // Array of objects
1141
In Java, there is no detailed distinction like this--specifically,
1142
there are only instances of classes. There are no pointers nor references.
1143
Because of this, SWIG unifies all of these types
1144
together in the wrapper code. For instance, if you actually had the
1145
above functions, it is perfectly legal to do this from Java:
1149
Foo f = new Foo(); // Create a Foo
1150
example.spam1(f); // Ok. Pointer
1151
example.spam2(f); // Ok. Reference
1152
example.spam3(f); // Ok. Value.
1153
example.spam4(f); // Ok. Array (1 element)
1157
Similar behavior occurs for return values. For example, if you had
1158
functions like this,
1168
then all three functions will return a pointer to some <tt>Foo</tt> object.
1169
Since the third function (spam7) returns a value, newly allocated memory is used
1170
to hold the result and a pointer is returned (Java will release this memory
1171
when the returned object's finalizer is run by the garbage collector).
1173
<a name="null_pointers"></a>
1174
<a name="n25"></a><H4>17.3.10.1 Null pointers</H4>
1177
Working with null pointers is easy.
1178
A Java <tt>null</tt> can be used whenever a method expects a proxy class or typewrapper class.
1179
However, it is not possible to pass null to C/C++ functions that take parameters by value or by reference.
1180
If you try you will get a NullPointerException.
1184
example.spam1(null); // Pointer - ok
1185
example.spam2(null); // Reference - NullPointerException
1186
example.spam3(null); // Value - NullPointerException
1187
example.spam4(null); // Array - ok
1191
For <tt>spam1</tt> and <tt>spam4</tt> above the Java <tt>null</tt> gets translated into a NULL pointer for passing to the C/C++ function.
1192
The converse also occurs, that is, NULL pointers are translated into <tt>null</tt> Java objects when returned from a C/C++ function.
1194
<a name="overloaded_functions"></a>
1195
<a name="n26"></a><H3>17.3.11 C++ overloaded functions</H3>
1198
C++ overloaded functions, methods, and constructors are mostly supported by SWIG. For example,
1199
if you have two functions like this:
1208
You can use them in Java in a straightforward manner:
1213
foo("Hello"); // foo(char *c)
1217
Similarly, if you have a class like this,
1230
you can write Java code like this:
1234
Foo f = new Foo(); // Create a Foo
1235
Foo g = new Foo(f); // Copy f
1239
Overloading support is not quite as flexible as in C++. Sometimes there are methods that SWIG
1240
can't disambiguate as there can be more than one C++ type mapping onto a single Java type. For example:
1245
void spam(unsigned short);
1249
Here both int and unsigned short map onto a Java int.
1250
Here is another example:
1259
If declarations such as these appear, you will get a warning message like this:
1263
example.i:12: Warning(509): Overloaded spam(unsigned short) is shadowed by spam(int) at example.i:11.
1266
The generated Java code will not compile either.
1268
To fix this, you either need to ignore or rename one of the methods. For example:
1272
%rename(spam_short) spam(short);
1275
void spam(short); // Accessed as spam_short
1283
%ignore spam(short);
1286
void spam(short); // Ignored
1292
<a name="namespaces"></a>
1293
<a name="n27"></a><H3>17.3.12 C++ namespaces</H3>
1296
SWIG is aware of C++ namespaces, but namespace names do not appear in
1297
the module nor do namespaces result in a module that is broken up into
1298
submodules or packages. For example, if you have a file like this,
1313
it works in Java as follows:
1317
int f = example.fact(3);
1318
Vector v = new Vector();
1320
double y = v.getY();
1324
If your program has more than one namespace, name conflicts (if any) can be resolved using <tt>%rename</tt>
1329
%rename(Bar_spam) Bar::spam;
1341
If you have more than one namespace and your want to keep their
1342
symbols separate, consider wrapping them as separate SWIG modules.
1343
Each SWIG module can be placed into a separate package.
1345
<a name="templates"></a>
1346
<a name="n28"></a><H3>17.3.13 C++ templates</H3>
1349
C++ templates don't present a huge problem for SWIG. However, in order
1350
to create wrappers, you have to tell SWIG to create wrappers for a particular
1351
template instantiation. To do this, you use the <tt>%template</tt> directive.
1361
template<class T1, class T2>
1363
typedef T1 first_type;
1364
typedef T2 second_type;
1368
pair(const T1&, const T2&);
1372
%template(pairii) pair<int,int>;
1380
pairii p = new pairii(3,4);
1381
int first = p.getFirst();
1382
int second = p.getSecond();
1386
Obviously, there is more to template wrapping than shown in this example.
1387
More details can be found in the <a href="SWIGPlus.html">SWIG and C++</a> chapter.
1389
<a name="smart_pointers"></a>
1390
<a name="n29"></a><H3>17.3.14 C++ Smart Pointers</H3>
1393
In certain C++ programs, it is common to use classes that have been wrapped by
1394
so-called "smart pointers." Generally, this involves the use of a template class
1395
that implements <tt>operator->()</tt> like this:
1399
template<class T> class SmartPtr {
1407
Then, if you have a class like this,
1419
A smart pointer would be used in C++ as follows:
1423
SmartPtr<Foo> p = CreateFoo(); // Created somehow (not shown)
1426
int y = p->bar(); // Foo::bar
1430
To wrap this in Java, simply tell SWIG about the <tt>SmartPtr</tt> class and the low-level
1431
<tt>Foo</tt> object. Make sure you instantiate <tt>SmartPtr</tt> using <tt>%template</tt> if necessary.
1438
%template(SmartPtrFoo) SmartPtr<Foo>;
1443
Now, in Java, everything should just "work":
1447
SmartPtrFoo p = example.CreateFoo(); // Create a smart-pointer somehow
1448
p.setX(3); // Foo::x
1449
int y = p.bar(); // Foo::bar
1453
If you ever need to access the underlying pointer returned by <tt>operator->()</tt> itself,
1454
simply use the <tt>__deref__()</tt> method. For example:
1458
Foo f = p.__deref__(); // Returns underlying Foo *
1462
<a name="further_details"></a>
1463
<a name="n30"></a><H2>17.4 Further details on the generated Java classes</H2>
1466
In the previous section, a high-level view of Java wrapping was
1467
presented. A key component of this wrapping is that structures and
1468
classes are wrapped by Java proxy classes and type wrapper classes are used
1469
in situations where no proxies are generated. This provides a very
1470
natural, type safe Java interface to the C/C++ code and fits in with the Java programing paradigm.
1471
However, a number of low-level details were omitted. This section provides a brief overview
1472
of how the proxy classes work and then covers the type wrapper classes.
1473
First, the crucial intermediary JNI class is considered.
1475
<a name="imclass"></a>
1476
<a name="n31"></a><H3>17.4.1 The intermediary JNI class</H3>
1479
In the <a href="SWIG.html">"SWIG basics"</a> and <a href="SWIGPlus.html">"SWIG and C++"</a> chapters,
1480
details of low-level structure and class wrapping are described. To summarize those chapters, if you
1481
have a global function and class like this
1488
int spam(int num, Foo* foo);
1490
void egg(Foo* chips);
1494
then SWIG transforms the class into a set of low-level procedural wrappers.
1495
These procedural wrappers essentially perform the equivalent of this C++ code:
1502
void delete_Foo(Foo *f) {
1505
int Foo_x_get(Foo *f) {
1508
void Foo_x_set(Foo *f, int value) {
1511
int Foo_spam(Foo *f, int num, Foo* foo) {
1512
return f->spam(num, foo);
1517
These procedural function names don't actually exist, but their functionality appears inside the generated
1518
JNI functions. The JNI functions have to follow a particular naming convention so the function names are actually:
1522
JNIEXPORT jlong JNICALL Java_exampleJNI_new_1Foo(JNIEnv *jenv, jclass jcls);
1523
JNIEXPORT void JNICALL Java_exampleJNI_delete_1Foo(JNIEnv *jenv, jclass jcls, jlong jarg1);
1524
JNIEXPORT void JNICALL Java_exampleJNI_set_1Foo_1x(JNIEnv *jenv, jclass jcls, jlong jarg1, jint jarg2);
1525
JNIEXPORT jint JNICALL Java_exampleJNI_get_1Foo_1x(JNIEnv *jenv, jclass jcls, jlong jarg1);
1526
JNIEXPORT jint JNICALL Java_exampleJNI_Foo_1spam(JNIEnv *jenv, jclass jcls, jlong jarg1, jint jarg2, jlong jarg3);
1527
JNIEXPORT void JNICALL Java_exampleJNI_egg(JNIEnv *jenv, jclass jcls, jlong jarg1);
1531
For every JNI C function there has to be a static native Java function. These appear in the intermediary JNI class:
1536
public final static native long new_Foo();
1537
public final static native void delete_Foo(long jarg1);
1538
public final static native void set_Foo_x(long jarg1, int jarg2);
1539
public final static native int get_Foo_x(long jarg1);
1540
public final static native int Foo_spam(long jarg1, int jarg2, long jarg3);
1541
public final static native void egg(long jarg1);
1546
This class contains the complete Java - C/C++ interface so all function calls go via this class.
1547
As this class acts as a go-between for all JNI calls to C/C++ code from the Java <a href="#java_proxy_classes">proxy classes</a>, <a href="#type_wrapper_classes">type wrapper classes</a> and <a href="#java_module_class">module class</a>, it is known as the intermediary JNI class.
1550
You may notice that SWIG uses a Java long wherever a pointer or class object needs traversing the Java-C/C++ boundary.
1551
This approach leads to minimal JNI code which makes for better performance as JNI code involves a lot of string manipulation.
1552
SWIG uses Java code wherever possible as it is compiled into byte code which requires fewer string operations.
1555
The functions in the intermediary JNI class cannot be accessed outside of its package. Access to them is gained through the module class for globals otherwise the appropriate proxy class.
1558
The name of the intermediary JNI class can be changed from its default, that is, the module name with JNI appended after it.
1559
The module directive attribute <tt>jniclassname</tt> is used to achieve this:
1563
%module (jniclassname="name") modulename
1567
If <tt>name</tt> is the same as <tt>modulename</tt> then the module class name gets changed
1568
from <tt>modulename</tt> to <tt>modulenameModule</tt>.
1570
<a name="imclass_pragmas"></a>
1571
<a name="n32"></a><H4>17.4.1.1 The intermediary JNI class pragmas</H4>
1574
The intermediary JNI class can be tailored through the use of pragmas, but is not commonly done. The pragmas for this class are:
1579
<td><b>Pragma</b></td>
1580
<td><b>Description</b></td>
1584
<td>jniclassbase </td> <td>Base class for the intermediary JNI class</td>
1587
<td>jniclassclassmodifiers </td> <td>Class modifiers for the intermediary JNI class</td>
1590
<td>jniclasscode </td> <td>Java code is copied verbatim into the intermediary JNI class</td>
1593
<td>jniclassimports </td> <td>Java code, usually one or more import statements, placed before the intermediary JNI class definition</td>
1596
<td>jniclassinterfaces </td> <td>Comma separated interface classes for the intermediary JNI class</td>
1601
The pragma code appears in the generated intermediary JNI class where you would expect:
1605
[ jniclassimports pragma ]
1606
[ jniclassmodifiers pragma ] class jniclassname extends [ jniclassbase pragma ] implements [ jniclassinterfaces pragma ] {
1607
[ jniclasscode pragma ]
1608
... SWIG generated native methods ...
1613
The <tt>jniclasscode</tt> pragma is quite useful for adding in a static block for loading the shared library / dynamic link library and demonstrates how pragmas work:
1617
%pragma(java) jniclasscode=%{
1620
System.loadLibrary("example");
1621
} catch (UnsatisfiedLinkError e) {
1622
System.err.println("Native code library failed to load. \n" + e);
1630
Pragmas will take either <tt>""</tt> or <tt>%{ %}</tt> as delimeters.
1631
For example, let's change the intermediary JNI class access attribute to public.
1635
%pragma(java) jniclassclassmodifiers="public"
1639
All the methods in the intermediary JNI class will then be callable outside of the package as the method modifiers are public by default.
1641
<a name="java_module_class"></a>
1642
<a name="n33"></a><H3>17.4.2 The Java module class</H3>
1645
All global functions and variable getters/setters appear in the module class. For our example, there is just one function:
1649
public class example {
1650
public static void egg(Foo chips) {
1651
exampleJNI.egg(Foo.getCPtr(chips));
1657
The module class is necessary as there is no such thing as a global in Java so all the C globals are put into this class. They are generated as static functions and so must be accessed as such by using the module name in the static function call:
1661
example.egg(new Foo());
1665
The primary reason for having the module class wrapping the calls in the intermediary JNI class is to implement static type checking. In this case only a <tt>Foo</tt> can be passed to the <tt>egg</tt> function, whereas any <tt>long</tt> can be passed to the <tt>egg</tt> function in the intermediary JNI class.
1667
<a name="module_class_pragmas"></a>
1668
<a name="n34"></a><H4>17.4.2.1 The Java module class pragmas</H4>
1671
The module class can be tailored through the use of pragmas, in the same manner as the intermediary JNI class. The pragmas are similarly named and are used in the same way. The complete list follows:
1676
<td><b>Pragma</b></td>
1677
<td><b>Description</b></td>
1680
<td>modulebase </td> <td>Base class for the module class</td>
1683
<td>moduleclassmodifiers </td> <td>Class modifiers for the module class</td>
1686
<td>modulecode </td> <td>Java code is copied verbatim into the module class</td>
1689
<td>moduleimports </td> <td>Java code, usually one or more import statements, placed before the module class definition</td>
1692
<td>moduleinterfaces </td> <td>Comma separated interface classes for the module class</td>
1699
The pragma code appears in the generated module class like this:
1703
[ moduleimports pragma ]
1704
[ modulemodifiers pragma ] class modulename extends [ modulebase pragma ] implements [ moduleinterfaces pragma ] {
1705
[ modulecode pragma ]
1706
... SWIG generated wrapper functions ...
1711
See <a href="#imclass_pragmas">The intermediary JNI class pragmas</a> section for further details on using pragmas.
1714
<a name="java_proxy_classes"></a>
1715
<a name="n35"></a><H3>17.4.3 Java proxy classes</H3>
1718
A Java proxy class is generated for each structure, union or C++ class that is wrapped.
1719
The default proxy class for our previous example looks like this:
1724
private long swigCPtr;
1725
protected boolean swigCMemOwn;
1727
protected Foo(long cPtr, boolean cMemoryOwn) {
1728
swigCMemOwn = cMemoryOwn;
1732
protected void finalize() {
1736
public void delete() {
1737
if(swigCPtr != 0 && swigCMemOwn) {
1738
exampleJNI.delete_Foo(swigCPtr);
1739
swigCMemOwn = false;
1744
protected static long getCPtr(Foo obj) {
1745
return obj.swigCPtr;
1748
public void setX(int x) {
1749
exampleJNI.set_Foo_x(swigCPtr, x);
1753
return exampleJNI.get_Foo_x(swigCPtr);
1756
public int spam(int num, Foo foo) {
1757
return exampleJNI.Foo_spam(swigCPtr, num, Foo.getCPtr(foo));
1761
this(exampleJNI.new_Foo(), true);
1768
This class merely holds a pointer to the underlying C++ object (<tt>swigCPtr</tt>).
1769
It also contains all the methods in the C++ class it is proxying plus getters and setters for public
1770
member variables. These functions call the native methods in the intermediary JNI class.
1771
The advantage of having this extra layer is the type safety that the proxy class functions offer.
1772
It adds static type checking which leads to fewer surprises at runtime.
1773
For example, you can see that if you attempt to use the <tt> spam() </tt>
1774
function it will only compile when the parameters passed are an <tt>int</tt> and a <tt>Foo</tt>.
1775
From a user's point of view, it makes the class work as if it were a Java class:
1781
int y = f.spam(5, new Foo());
1785
<a name="memory_management"></a>
1786
<a name="n36"></a><H4>17.4.3.1 Memory management</H4>
1789
Each proxy class has an ownership flag <tt>swigCMemOwn</tt>. The value of this
1790
flag determines who is responsible for deleting the underlying C++ object. If set to <tt>true</tt>,
1791
the proxy class's finalizer will destroy the C++ object when the proxy class is
1792
garbage collected. If set to false, then the destruction of the proxy class has no effect on the C++ object.
1795
When an object is created by a constructor or returned by value, Java automatically takes
1796
ownership of the result.
1797
On the other hand, when pointers or references are returned to Java, there is often no way to know where
1798
they came from. Therefore, the ownership is set to false. For example:
1817
Foo f = new Foo(); // f.swigCMemOwn = true
1818
Foo f1 = f.bar1(); // f1.swigCMemOwn = true
1819
Foo f2 = f.bar2(); // f2.swigCMemOwn = false
1820
Foo f3 = f.bar3(); // f3.swigCMemOwn = false
1824
This behavior for pointers and references is especially important for classes that act as containers.
1825
For example, if a method returns a pointer to an object
1826
that is contained inside another object, you definitely don't want
1827
Java to assume ownership and destroy it!
1830
For the most part, memory management issues remain hidden. However,
1831
there are situations where you might have to manually
1832
change the ownership of an object. For instance, consider code like this:
1840
void set_value(Obj *v) { value = v; }
1845
Now, consider the following Java code:
1849
Node n = new Node(); // Create a node
1851
Obj o = new Obj(); // Create an object
1852
n.set_value(o); // Set value
1853
} // o goes out of scope
1857
In this case, the Node <tt>n</tt> is holding a reference to
1858
<tt>o</tt> internally. However, SWIG has no way to know that this
1859
has occurred. The Java proxy class still thinks that it has ownership of
1860
<tt>o</tt>. As <tt>o</tt> has gone out of scope, it could be garbage collected in which case the C++ destructor
1861
will be invoked and <tt>n</tt> will then be holding a stale-pointer to <tt>o</tt>. If
1862
you're lucky, you will only get a segmentation fault.
1865
To work around this, the ownership flag of <tt>o</tt> needs changing to <tt>false</tt>.
1866
The ownership flag is a private member variable of the proxy class so this is not possible without some customization of the proxy class.
1867
This is achieved using a typemap to add pure Java code to the proxy class and is detailed later in the section on typemaps.
1870
Sometimes a function will create memory and return a pointer to a newly allocated object.
1871
SWIG has no way of knowing this so by default the proxy class does not manage the returned object.
1872
However, you can tell the proxy class to manage the memory if you specify the <tt>%newobject</tt> directive. Consider:
1879
static Obj *createObj() { return new Obj(); }
1884
If we call the factory function, then we have to manually delete the memory:
1888
Obj obj = Factory.createObj(); // obj.swigCMemOwn = false
1894
Now add in the %newobject directive:
1898
%newobject Factory::createObj();
1903
static Obj *createObj() { return new Obj(); }
1908
A call to <tt>delete()</tt> is no longer necessary as the garbage collector will make the C++ destructor call because <tt>swigCMemOwn</tt> is now true.
1912
Obj obj = Factory.createObj(); // obj.swigCMemOwn = true;
1918
<a name="inheritance_mirroring"></a>
1919
<a name="n37"></a><H4>17.4.3.2 Inheritance</H4>
1922
Java proxy classes will mirror C++ inheritance chains. For example, given the base class <tt>Base</tt> and its derived class </tt>Derived</tt>:
1927
virtual double foo();
1930
class Derived : public Base {
1932
virtual double foo();
1936
The base class is generated much like any other proxy class seen so far:
1940
private long swigCPtr;
1941
protected boolean swigCMemOwn;
1943
protected Base(long cPtr, boolean cMemoryOwn) {
1944
swigCMemOwn = cMemoryOwn;
1948
protected void finalize() {
1952
public void delete() {
1953
if(swigCPtr != 0 && swigCMemOwn) {
1954
exampleJNI.delete_Base(swigCPtr);
1955
swigCMemOwn = false;
1960
protected static long getCPtr(Base obj) {
1961
return obj.swigCPtr;
1964
public double foo() {
1965
return exampleJNI.Base_foo(swigCPtr);
1969
this(exampleJNI.new_Base(), true);
1974
The <tt>Derived</tt> class extends <tt>Base</tt> mirroring the C++ class inheritance hierarchy.
1977
public class Derived extends Base {
1978
private long swigCPtr;
1980
protected Derived(long cPtr, boolean cMemoryOwn) {
1981
super(exampleJNI.SWIGDerivedToBase(cPtr), cMemoryOwn);
1985
protected void finalize() {
1989
public void delete() {
1990
if(swigCPtr != 0 && swigCMemOwn) {
1991
exampleJNI.delete_Derived(swigCPtr);
1992
swigCMemOwn = false;
1998
protected static long getCPtr(Derived obj) {
1999
return obj.swigCPtr;
2002
public double foo() {
2003
return exampleJNI.Derived_foo(swigCPtr);
2007
this(exampleJNI.new_Derived(), true);
2012
Note the memory ownership is controlled by the base class.
2013
However each class in the inheritance hierarchy has its own pointer value which is obtained during construction.
2014
The <tt>SWIGDerivedToBase()</tt> call converts the pointer from a <tt>Derived *</tt> to a <tt>Base *</tt> as C++ compilers are free to implement
2015
pointers in the inheritance hierarchy with different values.
2019
It is of course possible to extend <tt>Base</tt> using your own Java classes.
2020
If <tt>Derived</tt> is provided by the C++ code, you could for example add in a pure Java class <tt>Extended</tt> derived from <tt>Base</tt>.
2021
There is a caveat and that is any C++ code will not know about your pure Java class <tt>Extended</tt> so this type of derivation is restricted.
2022
However, true cross language polymorphism can be achieved using the <a href="#java_directors">directors</a> feature.
2026
<a name="proxy_classes_gc"></a>
2027
<a name="n38"></a><H4>17.4.3.3 Proxy classes and garbage collection</H4>
2030
By default each proxy class has a <tt>delete()</tt> and a <tt>finalize()</tt> method.
2031
The <tt>finalize()</tt> method calls <tt>delete()</tt> which frees any malloc'd memory for wrapped C structs or calls the C++ class destructors.
2032
The idea is for <tt>delete()</tt> to be called when you have finished with the C/C++ object.
2033
Ideally you need not call <tt>delete()</tt>, but rather leave it to the garbage collector to call it from the finalizer.
2034
The unfortunate thing is that Sun, in their wisdom, do not guarantee that the finalizers will be called.
2035
When a program exits, the garbage collector does not always call the finalizers.
2036
Depending on what the finalizers do and which operating system you use, this may or may not be a problem.
2039
If the <tt>delete()</tt> call into JNI code is just for memory handling, there is not a problem when run on most operating systems, for example Windows and Unix.
2040
Say your JNI code creates memory on the heap which your finalizers should clean up, the finalizers may or may not be called before the program exits.
2041
In Windows and Unix all memory that a process uses is returned to the system on exit, so this isn't a problem.
2042
This is not the case in some operating systems like vxWorks.
2043
If however, your finalizer calls into JNI code invoking the C++ destructor which in turn releases a TCP/IP socket for example, there is no guarantee that it will be released.
2044
Note that with long running programs the garbage collector will eventually run, thereby calling any unreferenced object's finalizers.
2047
Some not so ideal solutions are:
2050
Call the <tt>System.runFinalizersOnExit(true)</tt> or <tt>Runtime.getRuntime().runFinalizersOnExit(true)</tt> to ensure the finalizers are called before the program exits. The catch is that this is a deprecated function call as the documenation says:
2052
This method is inherently unsafe. It may result in finalizers being called on live objects while other threads are concurrently manipulating those objects, resulting in erratic behavior or deadlock.
2054
In many cases you will be lucky and find that it works, but it is not to be advocated.
2055
Have a look at <a href=http://java.sun.com>Sun's Java web site</a> and search for <tt>runFinalizersOnExit</tt>.
2059
From jdk1.3 onwards a new function, <tt>addShutdownHook()</tt>, was introduced which is guaranteed to be called when your program exits.
2060
You can encourage the garbage collector to call the finalizers, for example, add this static block to the class that has the <tt>main()</tt> function:
2063
Runtime.getRuntime().addShutdownHook(
2065
public void run() { System.gc(); System.runFinalization(); }
578
The functions associated with this class can throw a C++ range exception for an out-of-bounds array access. We can catch the C++ exception and rethrow it as a Java exception by specifying the following in an interface file :<p>
2070
Although this usually works, the documentation doesn't guarantee that <tt>runFinalization()</tt> will actually call the finalizers.
2071
As the the shutdown hook is guaranteed you could also make a JNI call to clean up any resources that are being tracked by the C/C++ code.
2075
Call the <tt>delete()</tt> function manually which will immediately invoke the C++ destructor.
2076
As a suggestion it may be a good idea to set the object to null so that should the object be inadvertantly used again a Java null pointer exception is thrown, the alternative would crash the JVM by using a null C pointer.
2077
For example given a SWIG generated class A:
2082
// any use of myA here would crash the JVM
2084
// any use of myA here would cause a Java null pointer exception to be thrown
2086
The SWIG generated code ensures that the memory is not deleted twice, in the event the finalizers get called in addition to the manual <tt>delete()</tt> call.
2091
Write your own object manager in Java.
2092
You could derive all SWIG classes from a single base class which could track which objects have had their finalizers run, then call the rest of them on program termination.
2093
The section on <a href="#java_typemaps">Java typemaps</a> details how to specify a pure Java base class.
2097
<a name="type_wrapper_classes"></a>
2098
<a name="n39"></a><H3>17.4.4 Type wrapper classes</H3>
2101
The generated type wrapper class, for say an <tt>int *</tt>, looks like this:
2104
public class SWIGTYPE_p_int {
2105
private long swigCPtr;
2107
protected SWIGTYPE_p_int(long cPtr, boolean bFutureUse) {
2111
protected SWIGTYPE_p_int() {
2115
protected static long getCPtr(SWIGTYPE_p_int obj) {
2116
return obj.swigCPtr;
2121
The methods do not have public access, so by default it is impossible to do anything with objects of this class other than
2122
pass them around. The methods in the class are part of the inner workings of SWIG.
2123
If you need to mess around with pointers you will have to use some typemaps specific to the Java module to achieve this.
2124
The section on <a href="#java_typemaps">Java typemaps</a> details how to modify the generated code.
2127
Note that if you use a pointer or reference to a proxy class in a function then no type wrapper class is generated because the proxy class can be used
2128
as the function parameter. If however, you need anything more complicated like a pointer to a pointer to a proxy class then a typewrapper class
2129
is generated for your use.
2132
Note that SWIG generates a type wrapper class and not a proxy class when it has not parsed the definition of a type that gets used.
2133
For example, say SWIG has not parsed the definition of <tt>class Snazzy</tt> because it is in a header file that you may have forgotten to use the <tt>%include</tt> directive on.
2134
Should SWIG parse <tt>Snazzy *</tt> being used in a function parameter, it will then generates a type wrapper class around a <tt>Snazzy</tt> pointer.
2135
Also recall from earlier that SWIG will use a pointer when a class is passed by value or by reference:
2139
void spam(Snazzy *x, Snazzy &y, Snazzy z);
2143
Should SWIG not know anything about <tt>Snazzy</tt> then a <tt>SWIGTYPE_p_Snazzy</tt> must be used for all 3 parameters in the <tt>spam</tt> function.
2144
The Java function generated is:
2148
public static void spam(SWIGTYPE_p_Snazzy x, SWIGTYPE_p_Snazzy y, SWIGTYPE_p_Snazzy z) { ... }
2153
Note that typedefs are tracked by SWIG and the typedef name is used to construct the type wrapper class name. For example, consider the case where <tt>Snazzy</tt> is a typedef to an <tt>int</tt> which SWIG does parse:
2159
void spam(Snazzy *x, Snazzy &y, Snazzy z);
2163
Because the typedefs have been tracked the Java function generated is:
2166
public static void spam(SWIGTYPE_p_int x, SWIGTYPE_p_int y, int z) { ... }
2172
<a name="java_directors"></a>
2173
<a name="n40"></a><H2>17.5 Cross language polymorphism using directors (experimental)</H2>
2176
Proxy classes provide a natural, object-oriented way to wrap C++ classes.
2177
As described earlier, each proxy instance has an associated C++ instance, and method calls from Java to the proxy are passed to the C++ instance transparently via C wrapper functions.
2180
This arrangement is asymmetric in the sense that no corresponding mechanism exists to pass method calls down the inheritance chain from C++ to Java.
2181
In particular, if a C++ class has been extended in Java (by deriving from the proxy class), these classes will not be visible from C++ code.
2182
Virtual method calls from C++ are thus not able to access the lowest implementation in the inheritance chain.
2185
SWIG can address this problem and make the relationship between C++ classes and proxy classes more symmetric.
2186
To achieve this goal, new classes called directors are introduced at the bottom of the C++ inheritance chain.
2187
The job of the directors is to route method calls correctly, either to C++ implementations higher in the inheritance chain or to Java implementations lower in the inheritance chain.
2188
The upshot is that C++ classes can be extended in Java and from C++ these extensions look exactly like native C++ classes.
2189
Neither C++ code nor Java code needs to know where a particular method is implemented: the combination of proxy classes, director classes, and C wrapper functions transparently takes care of all the cross-language method routing.
2191
<a name="java_enabling_directors"></a>
2192
<a name="n41"></a><H3>17.5.1 Enabling directors</H3>
2195
The director feature is disabled by default.
2196
To use directors you must make two changes to the interface file.
2197
First, add the "directors" option to the %module directive, like this:
2201
%module(directors="1") modulename
2205
Without this option no director code will be generated.
2206
Second, you must use the %feature("director") directive to tell SWIG which classes and methods should get directors.
2207
The %feature directive can be applied globally, to specific classes, and to specific methods, like this:
2211
// generate directors for all classes that have virtual methods
2212
%feature("director");
2214
// genarate directors for all virtual methods in class Foo
2215
%feature("director") Foo;
2217
// generate a director for just Foo::bar()
2218
%feature("director") Foo::bar;
2222
You can use the %feature("nodirector") directive to turn off directors for specific classes or methods.
2227
%feature("director") Foo;
2228
%feature("nodirector") Foo::bar;
2232
will generate directors for all virtual methods of class Foo except bar().
2235
Directors can also be generated implicitly through inheritance.
2236
In the following, class Bar will get a director class that handles the methods one() and two() (but not three()):
2240
%feature("director") Foo;
2247
class Bar: public Foo {
2249
virtual void three();
2254
<a name="java_directors_classes"></a>
2255
<a name="n42"></a><H3>17.5.2 Director classes</H3>
2258
For each class that has directors enabled, SWIG generates a new class that derives from both the class in question and a special <tt>Swig::Director</tt> class.
2259
These new classes, referred to as director classes, can be loosely thought of as the C++ equivalent of the Java proxy classes.
2260
The director classes store a pointer to their underlying Java proxy classes.
2263
For simplicity let's ignore the <tt>Swig::Director</tt> class and refer to the original C++ class as the director's base class.
2264
By default, a director class extends all virtual methods in the inheritance chain of its base class (see the preceding section for how to modify this behavior).
2265
Thus all virtual method calls, whether they originate in C++ or in Java via proxy classes, eventually end up in at the implementation in the director class.
2266
The job of the director methods is to route these method calls to the appropriate place in the inheritance chain.
2267
By "appropriate place" we mean the method that would have been called if the C++ base class and its Java derived classes were seamlessly integrated.
2268
That seamless integration is exactly what the director classes provide, transparently skipping over all the messy JNI glue code that binds the two languages together.
2271
In reality, the "appropriate place" is one of only two possibilities: C++ or Java.
2272
Once this decision is made, the rest is fairly easy.
2273
If the correct implementation is in C++, then the lowest implementation of the method in the C++ inheritance chain is called explicitly.
2274
If the correct implementation is in Java, the Java API is used to call the method of the underlying Java object
2275
(after which the usual virtual method resolution in Java automatically finds the right implementation).
2279
<a name="java_directors_overhead"></a>
2280
<a name="n43"></a><H3>17.5.3 Overhead and code bloat</H3>
2283
Enabling directors for a class will generate a new director method for every virtual method in the class' inheritance chain.
2284
This alone can generate a lot of code bloat for large hierarchies.
2285
Method arguments that require complex conversions to and from Java types can result in large director methods.
2286
For this reason it is recommended that directors are selectively enabled only for specific classes that are likely to be extended in Java and used in C++.
2289
Although directors make it natural to mix native C++ objects with Java objects (as director objects),
2290
one should be aware of the obvious fact that method calls to Java objects from C++ will be much slower than calls to C++ objects.
2291
Additionally, compared to classes that do not use directors, the call routing in the director methods adds a small overhead.
2292
This situation can be optimized by selectively enabling director methods (using the %feature directive) for only those methods that are likely to be extended in Java.
2295
<a name="java_directors_example"></a>
2296
<a name="n44"></a><H3>17.5.4 Simple directors example</H3>
2300
Consider the following SWIG interface file:
2305
%module(directors="1") example;
2307
%feature("director") DirectorBase;
2309
class DirectorBase {
2311
virtual ~DirectorBase() {}
2312
virtual void upcall_method() {}
2315
void callup(DirectorBase *director) {
2316
director->upcall_method();
2321
The following <code>directorDerived</code> Java class is derived from the Java proxy class <code>DirectorBase</code> and overrides <code>upcall_method()</code>.
2322
When C++ code invokes <code>upcall_method()</code>, the SWIG-generated C++ code redirects the call via JNI to the Java <code>directorDerived</code> subclass.
2323
Naturally, the SWIG generated C++ code and the generated Java intermediate class marshall and convert arguments between C++ and Java when needed.
2328
public class directorDerived extends DirectorBase {
2329
public directorDerived() {
2332
public void upcall_method() {
2333
System.out.println("directorDerived::upcall_method() invoked.");
2339
Running the following Java code
2343
directorDerived director = new directorDerived();
2344
example.callup(director);
2348
will result in the following being output:
2352
directorDerived::upcall_method() invoked.
2356
<a name="common_customization"></a>
2357
<a name="n45"></a><H2>17.6 Common customization features</H2>
2360
An earlier section presented the absolute basics of C/C++ wrapping. If you do nothing
2361
but feed SWIG a header file, you will get an interface that mimics the behavior
2362
described. However, sometimes this isn't enough to produce a nice module. Certain
2363
types of functionality might be missing or the interface to certain functions might
2364
be awkward. This section describes some common SWIG features that are used
2365
to improve the interface to existing C/C++ code.
2367
<a name="helper_functions"></a>
2368
<a name="n46"></a><H3>17.6.1 C/C++ helper functions</H3>
2371
Sometimes when you create a module, it is missing certain bits of functionality. For
2372
example, if you had a function like this
2376
typedef struct Image {...};
2377
void set_transform(Image *im, double m[4][4]);
2381
it would be accessible from Java, but there may be no easy way to call it.
2382
The problem here is that a type wrapper class is generated for the two dimensional array parameter so
2383
there is no easy way to construct and manipulate a suitable
2384
<tt>double [4][4]</tt> value. To fix this, you can write some extra C helper
2385
functions. Just use the <tt>%inline</tt> directive. For example:
2390
/* Note: double[4][4] is equivalent to a pointer to an array double (*)[4] */
2391
double (*new_mat44())[4] {
2392
return (double (*)[4]) malloc(16*sizeof(double));
2394
void free_mat44(double (*x)[4]) {
2397
void mat44_set(double x[4][4], int i, int j, double v) {
2400
double mat44_get(double x[4][4], int i, int j) {
2407
From Java, you could then write code like this:
2411
Image im = new Image();
2412
SWIGTYPE_p_a_4__double a = example.new_mat44();
2413
example.mat44_set(a,0,0,1.0);
2414
example.mat44_set(a,1,1,1.0);
2415
example.mat44_set(a,2,2,1.0);
2417
example.set_transform(im,a);
2418
example.free_mat44(a);
2422
Admittedly, this is not the most elegant looking approach. However, it works and it wasn't too
2423
hard to implement. It is possible to improve on this using Java code, typemaps, and other
2424
customization features as covered in later sections, but sometimes helper functions are a quick and easy solution to difficult cases.
2426
<a name="class_extension"></a>
2427
<a name="n47"></a><H3>17.6.2 Class extension with %extend</H3>
2430
One of the more interesting features of SWIG is that it can extend
2431
structures and classes with new methods or constructors.
2432
Here is a simple example:
2438
#include "someheader.h"
2447
static char tmp[1024];
2448
sprintf(tmp,"Vector(%g,%g,%g)", self->x,self->y,self->z);
2451
Vector(double x, double y, double z) {
2452
Vector *v = (Vector *) malloc(sizeof(Vector));
2466
Vector v = new Vector(2,3,4);
2467
System.out.println(v);
2478
<tt>%extend</tt> works with both C and C++ code. It does not modify the underlying object
2479
in any way---the extensions only show up in the Java interface.
2481
<a name="exception_handling"></a>
2482
<a name="n48"></a><H3>17.6.3 Exception handling with %exception</H3>
2485
If a C or C++ function throws an error, you may want to convert that error into a Java
2486
exception. To do this, you can use the <tt>%exception</tt> directive. The <tt>%exception</tt> directive
2487
simply lets you rewrite part of the generated wrapper code to include an error check.
2490
In C, a function often indicates an error by returning a status code (a negative number
2491
or a NULL pointer perhaps). Here is a simple example of how you might handle that:
2498
jclass clazz = (*jenv)->FindClass(jenv, "java/lang/OutOfMemoryError");
2499
(*jenv)->ThrowNew(jenv, clazz, "Not enough memory");
2503
void *malloc(size_t nbytes);
2511
SWIGTYPE_p_void a = example.malloc(2000000000);
2515
will produce a familiar looking Java exception:
2519
Exception in thread "main" java.lang.OutOfMemoryError: Not enough memory
2520
at exampleJNI.malloc(Native Method)
2521
at example.malloc(example.java:16)
2522
at main.main(main.java:112)
2526
If a library provides some kind of general error handling framework, you can also use
2533
if (err_occurred()) {
2534
jclass clazz = (*jenv)->FindClass(jenv, "java/lang/OutOfMemoryError");
2535
(*jenv)->ThrowNew(jenv, clazz, "Not enough memory");
2539
void *malloc(size_t nbytes);
2543
No declaration name is given to <tt>%exception</tt>, it is applied to all wrapper functions.
2544
The <tt> $action </tt> is a SWIG special variable and is replaced by the C/C++ function call being wrapped.
2545
The <tt> return $null; </tt> handles all native method return types, namely those that have a void return and those that do not.
2546
This is useful for typemaps that will be used in native method returning all return types.
2548
<a href="#special_variables">Java special variables</a> for further explanation.
2551
C++ exceptions are also easy to handle.
2552
We can catch the C++ exception and rethrow it as a Java exception like this:<p>
2556
%exception getitem {
586
jclass clazz = jenv->FindClass("java/lang/Exception");
587
jenv->ThrowNew(clazz, "Range error");
2559
} catch (std::out_of_range &e) {
2560
jclass clazz = jenv->FindClass("java/lang/Exception");
2561
jenv->ThrowNew(clazz, "Range error");
593
What the above does is define swig exception handlers for two types of functions; namely those that are have a void return and those that do not. Both are needed to cover all types of JNI functions. The code excerpts above are inserted into all the JNI functions. The $action call is replaced by the C/C++ code being executed by the wrapper, for example the <tt>setitem</tt> call. Another special variable, $null, is useful for typemaps that will be used in JNI functions returning all return types. See the section on
594
<a href="#n124">Typemap variables</a> for further explanation.
598
The above uses the C++ JNI calling syntax as opposed to the C calling syntax and so will not compile as C.
599
It is however possible to write JNI calls in <a href="#n126">typemaps for both C and C++ compilation</a>.
600
The <tt>ThrowNew()</tt> JNI function must take a class derived from java.lang.Exception. The %exception typemap above could be tailored to individual needs.
602
When the C++ class throws a RangeError exception, our wrapper functions will catch it, turn it into a Java exception, and allow a graceful death as opposed to having some sort of mysterious JVM crash. Since SWIG's exception handling is user-definable, we are not limited to C++ exception handling. Please see the chapter on exception handling for more details and using the <tt>exception.i</tt> library for writing language-independent exception handlers.<p>
603
See the chapter on "<a href="Exceptions.html">Exception Handling</a>" for further examples on exceptions and how %exception can be targeted for use in a particular function.
605
If we use the following code:
609
DoubleArray arr = new DoubleArray(SIZE);
610
for (int i=0; i<SIZE; i++)
611
arr.setitem(i, (double)i);
612
for (int i=0; i<SIZE+1; i++) //Note the array over bounds
613
System.out.println(i + " " + arr.getitem(i));
616
Something similar to the following will be output when it is run:
623
Exception in thread "main" java.lang.Exception: Range error
624
at example.DoubleArray_getitem(Native Method)
625
at example.DoubleArray_getitem(Compiled Code)
626
at DoubleArray.getitem(Compiled Code)
627
at main.main(Compiled Code)
631
<a name="n7"></a><h2>Remapping C datatypes with typemaps</h2>
632
This section describes how SWIG's treatment of various C/C++ datatypes can be remapped using the SWIG <tt>%typemap</tt> directive. While not required, this section assumes some familiarity with the JNI. The reader is advised to be familiar with the chapter on SWIG typemaps. Also it is best to consult JNI documentation either online at <a href=http://java.sun.com>Sun's Java web site</a> or a good book on the JNI. The following two books are recommended:<p>
2568
Foo *getitem(int index); // Exception handler added
2574
The examples above first use the C JNI calling syntax then the C++ JNI calling syntax. The C++ calling syntax will not compile as C and also visa versa.
2575
It is however possible to write JNI calls which will compile under both C and C++ and is covered in the <a href="#typemaps_for_c_and_c++">Typemaps for both C and C++ compilation</a> section.
2578
The language-independent <tt>exception.i</tt> library file can also be used
2579
to raise exceptions. See the <a href="Library.html">SWIG Library</a> chapter.
2581
<a name="method_access"></a>
2582
<a name="n49"></a><H3>17.6.4 Method access with %javamethodmodifiers</H3>
2585
A Java feature called <tt>%javamethodmodifiers</tt> can be used to change the method modifiers from the default <tt>public</tt>. It applies to both module class methods and proxy class methods. For example:
2589
%javamethodmodifiers protect_me() "protected";
2594
Will produce the method in the module class with protected access.
2598
protected static void protect_me() {
2599
exampleJNI.protect_me();
2604
<a name="tips_techniques"></a>
2605
<a name="n50"></a><H2>17.7 Tips and techniques</H2>
2608
Although SWIG is largely automatic, there are certain types of wrapping problems that
2609
require additional user input. Examples include dealing with output parameters,
2610
strings and arrays. This chapter discusses the common techniques for
2611
solving these problems.
2613
<a name="input_output_parameters"></a>
2614
<a name="n51"></a><H3>17.7.1 Input and output parameters using primitive pointers and references</H3>
2617
A common problem in some C programs is handling parameters passed as simple pointers or references. For
2622
void add(int x, int y, int *result) {
2632
int sub(int *x, int *y) {
2638
The <tt>typemaps.i</tt> library file will help in these situations. For example:
2643
%include "typemaps.i"
2645
void add(int, int, int *OUTPUT);
2646
int sub(int *INPUT, int *INPUT);
2650
In Java, this allows you to pass simple values. For example:
2654
int result = example.sub(7,4);
2655
System.out.println("7 - 4 = " + result);
2657
example.add(3,4,sum);
2658
System.out.println("3 + 4 = " + sum[0]);
2668
Notice how the <tt>INPUT</tt> parameters allow integer values to be passed instead of pointers
2669
and how the <tt>OUTPUT</tt> parameter will return the result in the first element of the integer array.
2672
If you don't want to use the names <tt>INPUT</tt> or <tt>OUTPUT</tt>, use the <tt>%apply</tt>
2673
directive. For example:
2678
%include "typemaps.i"
2680
%apply int *OUTPUT { int *result };
2681
%apply int *INPUT { int *x, int *y};
2683
void add(int x, int y, int *result);
2684
int sub(int *x, int *y);
2689
If a function mutates one of its parameters like this,
2693
void negate(int *x) {
2699
you can use <tt>INOUT</tt> like this:
2703
%include "typemaps.i"
2705
void negate(int *INOUT);
2709
In Java, the input parameter is the first element in a 1 element array and is replaced by the output of the function. For example:
2714
example.negate(neg);
2715
System.out.println("Negative of 3 = " + neg[0]);
2719
And no prizes for guessing the output:
2724
These typemaps can also be applied to C++ references.
2725
The above examples would work the same if they had been defined using references instead of pointers.
2726
For example, the Java code to use the <tt>negate</tt> function would be the same if it were defined either as it is above:
2730
void negate(int *INOUT);
2733
or using a reference:
2736
void negate(int &INOUT);
2741
Note: Since most Java primitive types are immutable and are passed by value, it is not possible to
2742
perform in-place modification of a type passed as a parameter.
2745
Be aware that the primary purpose of the <tt>typemaps.i</tt> file is to support primitive datatypes.
2746
Writing a function like this
2750
void foo(Bar *OUTPUT);
2754
will not have the intended effect since <tt>typemaps.i</tt> does not define an OUTPUT rule for <tt>Bar</tt>.
2756
<a name="simple_pointers"></a>
2757
<a name="n52"></a><H3>17.7.2 Simple pointers</H3>
2760
If you must work with simple pointers such as <tt>int *</tt> or <tt>double *</tt> another approach to using
2761
<tt>typemaps.i</tt> is to use the <tt>cpointer.i</tt> pointer library file. For example:
2766
%include "cpointer.i"
2768
extern void add(int x, int y, int *result);
2769
%pointer_functions(int, intp);
2773
The <tt>%pointer_functions(type,name)</tt> macro generates five helper functions that can be used to create,
2774
destroy, copy, assign, and dereference a pointer. In this case, the functions are as follows:
2779
int *copy_intp(int *x);
2780
void delete_intp(int *x);
2781
void intp_assign(int *x, int value);
2782
int intp_value(int *x);
2786
In Java, you would use the functions like this:
2790
SWIGTYPE_p_int intPtr = example.new_intp();
2791
example.add(3,4,intPtr);
2792
int result = example.intp_value(intPtr);
2793
System.out.println("3 + 4 = " + result);
2797
If you replace <tt>%pointer_functions(int,intp)</tt> by <tt>%pointer_class(int,intp)</tt>, the interface is more class-like.
2801
intp intPtr = new intp();
2802
example.add(3,4,intPtr.cast());
2803
int result = intPtr.value();
2804
System.out.println("3 + 4 = " + result);
2808
See the <a href="Library.html">SWIG Library</a> chapter for further details.
2810
<a name="c_arrays"></a>
2811
<a name="n53"></a><H3>17.7.3 Wrapping C arrays with Java arrays</H3>
2814
SWIG can wrap arrays in a more natural Java manner than the default by using the <tt>arrays_java.i</tt> library file.
2815
Let's consider an example:
2819
%include "arrays_java.i";
2821
void populate(int x[]) {
2829
These one dimensional arrays can then be used as if they were Java arrays:
2833
int[] array = new int[4];
2834
example.populate(array);
2836
System.out.print("array: ");
2837
for (int i=0; i<array.length; i++)
2838
System.out.print(array[i] + " ");
2840
example.setArray(array);
2842
int[] global_array = example.getArray();
2844
System.out.print("\nglobal_array: ");
2845
for (int i=0; i<array.length; i++)
2846
System.out.print(global_array[i] + " ");
2850
Java arrays are always passed by reference, so any changes a function makes to the array will be seen by the calling function.
2851
Here is the output after running this code:
2855
array: 100 101 102 103
2856
global_array: 100 101 102 103
2860
Note that for assigning array variables the length of the C variable is used, so it is possible to use a Java array that is bigger than the C code will cope with.
2861
Only the number of elements in the C array will be used.
2862
However, if the Java array is not large enough then you are likely to get a segmentation fault or access violation, just like you would in C.
2863
When arrays are used in functions like <tt>populate</tt>, the size of the C array passed to the function is determined by the size of the Java array.
2865
Please be aware that the typemaps in this library are not efficient as all the elements are copied from the Java array to a C array whenever the array is passed to and from JNI code.
2866
There is an alternative approach using the SWIG array library and this is covered in the next.
2868
<a name="unbounded_c_arrays"></a>
2869
<a name="n54"></a><H3>17.7.4 Unbounded C Arrays</H3>
2872
Sometimes a C function expects an array to be passed as a pointer. For example,
2876
int sumitems(int *first, int nitems) {
2878
for (i = 0; i < nitems; i++) {
2886
One of the ways to wrap this is to apply the Java array typemaps that come in the <tt>arrays_java.i</tt> library file:
2890
%include "arrays_java.i"
2891
%apply int[ANY] {int *};
2895
The <tt>ANY</tt> size will ensure the typemap is applied to arrays of all sizes.
2896
You could narrow the typemap matching rules by specifying a particular array size.
2897
Now you can use a pure Java array and pass it to the C code:
2901
int[] array = new int[10000000]; // Array of 10-million integers
2902
for (int i=0; i<array.length; i++) { // Set some values
2905
int sum = example.sumitems(array,10000);
2906
System.out.println("Sum = " + sum);
2910
and the sum would be displayed:
2918
This approach is probably the most natural way to use arrays.
2919
However, it suffers from performance problems when using large arrays as a lot of copying
2920
of the elements occurs in transferring the array from the Java world to the C++ world.
2921
An alternative approach to using Java arrays for C arrays is to use an alternative SWIG library file <tt>carrays.i</tt>.
2922
This approach can be more efficient for large arrays as the array is accessed one element at a time.
2927
%include "carrays.i"
2928
%array_functions(int, intArray);
2932
The <tt>%array_functions(type,name)</tt> macro generates four helper functions that can be used to create and
2933
destroy arrays and operate on elements. In this case, the functions are as follows:
2937
int *new_intArray(int nelements);
2938
void delete_intArray(int *x);
2939
int intArray_getitem(int *x, int index);
2940
void intArray_setitem(int *x, int index, int value);
2944
In Java, you would use the functions like this:
2948
SWIGTYPE_p_int array = example.new_intArray(10000000); // Array of 10-million integers
2949
for (int i=0; i<10000; i++) { // Set some values
2950
example.intArray_setitem(array,i,i);
2952
int sum = example.sumitems(array,10000);
2953
System.out.println("Sum = " + sum);
2957
If you replace <tt>%array_functions(int,intp)</tt> by <tt>%array_class(int,intp)</tt>, the interface is more class-like
2958
and a couple more helper functions are available for casting between the array and the type wrapper class.
2962
%include "carrays.i"
2963
%array_class(int, intArray);
2967
The <tt>%array_class(type, name)</tt> macro creates wrappers for an unbounded array object that
2968
can be passed around as a simple pointer like <tt>int *</tt> or <tt>double *</tt>.
2969
For instance, you will be able to do this in Java:
2973
intArray array = new intArray(10000000); // Array of 10-million integers
2974
for (int i=0; i<10000; i++) { // Set some values
2977
int sum = example.sumitems(array.cast(),10000);
2978
System.out.println("Sum = " + sum);
2982
The array "object" created by <tt>%array_class()</tt> does not
2983
encapsulate pointers inside a special array object. In fact, there is
2984
no bounds checking or safety of any kind (just like in C). Because of
2985
this, the arrays created by this library are extremely low-level
2986
indeed. You can't iterate over them nor can you even query their
2987
length. In fact, any valid memory address can be accessed if you want
2988
(negative indices, indices beyond the end of the array, etc.).
2989
Needless to say, this approach is not going to suit all applications.
2990
On the other hand, this low-level approach is extremely efficient and
2991
well suited for applications in which you need to create buffers,
2992
package binary data, etc.
2994
<a name="java_typemaps"></a>
2995
<a name="n55"></a><H2>17.8 Java typemaps</H2>
2998
This section describes how you can modify SWIG's default wrapping behavior
2999
for various C/C++ datatypes using the <tt>%typemap</tt> directive.
3000
You are advised to be familiar with the the material in the "<a href="Typemaps.html">Typemaps</a>" chapter.
3001
While not absolutely essential knowledge, this section assumes some familiarity with the Java Native Interface (JNI).
3002
JNI documentation can be consulted either online at <a href=http://java.sun.com>Sun's Java web site</a> or from a good JNI book.
3003
The following two books are recommended:<p>
634
3005
<li> Title: 'Essential JNI: Java Native Interface.' Author: Rob Gordon. Publisher: Prentice Hall. ISBN: 0-13-679895-0. </li>
635
3006
<li> Title: 'The Java Native Interface: Programmer's Guide and Specification.' Author: Sheng Liang. Publisher: Addison-Wesley. ISBN: 0-201-32577-2. </li>
637
<a name="n121"></a><h3>Default type mapping</h3>
3010
Before proceeding, it should be stressed that typemaps are not a required
3011
part of using SWIG---the default wrapping behavior is enough in most cases.
3012
Typemaps are only used if you want to change some aspect of the generated code.
3014
<a name="default_primitive_type_mappings"></a>
3015
<a name="n56"></a><H3>17.8.1 Default primitive type mappings</H3>
638
3018
The following table lists the default type mapping from Java to C/C++.<p>
950
3495
</pre></blockquote>
953
<a name="n126"></a><h3> Typemaps for C and C++</h3>
954
JNI calls must be written differently depending on whether the code is being compiled as C or C++. For example C compilation requires syntax like
3497
<b><tt>$javainput, $jnicall and $owner</tt></b><br>
3498
The $javainput special variable is used in "javain" typemaps and $jnicall and $owner are used in "javaout" typemaps.
3499
$jnicall is analogous to $action in %exception. It is replaced by the call to the native method in the intermediary JNI class.
3500
$owner is replaced by either <tt>true</tt> if %newobject has been used, otherwise <tt>false</tt>.
3501
$javainput is analogous to the $input special variable. It is replaced by the parameter name.
3507
%typemap(javain) Class "Class.getCPtr($javainput)"
3508
%typemap(javain) unsigned short "$javainput"
3509
%typemap(javaout) Class * {
3510
return new Class($jnicall, $owner);
3515
Class * bar(Class cls, unsigned short ush) { return new Class(); };
3519
The generated proxy code is then:
3522
public static Class bar(Class cls, int ush) {
3523
return new Class(exampleJNI.bar(Class.getCPtr(cls), ush), false);
3527
Here $javainput has been replaced by <tt>cls</tt> and <tt>ush</tt>. $jnicall has been replaced by
3528
the native method call, <tt>exampleJNI.bar(...)</tt> and $owner has been replaced by <tt>false</tt>.
3529
If %newobject is used by adding the following at the beginning of our example:
3532
%newobject bar(Class cls, unsigned short ush);
3535
The generated code constructs the return type using <tt>true</tt> indicating the proxy class <tt>Class</tt> is responsible for destroying the C++ memory allocated for it in <tt>bar</tt>:
3538
public static Class bar(Class cls, int ush) {
3539
return new Class(exampleJNI.bar(Class.getCPtr(cls), ush), true);
3543
<b><tt>$jniinput, $javacall and $packagepath</tt></b><br>
3544
These special variables used in the directors typemaps. See <a href="#java_directors_typemaps">Director specific typemaps</a> for details.
3546
<a name="typemaps_for_c_and_c++"></a>
3547
<a name="n61"></a><H3>17.8.6 Typemaps for both C and C++ compilation</H3>
3550
JNI calls must be written differently depending on whether the code is being compiled as C or C++.
3551
For example C compilation requires the pointer to a function pointer struct member syntax like
955
3553
<blockquote><pre>
956
3554
const jclass clazz = (*jenv)->FindClass(jenv, "java/lang/String");
957
3555
</pre></blockquote>
958
whereas C++ code compilation of the same function call has to be written like this
3557
whereas C++ code compilation of the same function call is a member function call using a class pointer like
959
3559
<blockquote><pre>
960
3560
const jclass clazz = jenv->FindClass("java/lang/String");
961
3561
</pre></blockquote>
962
To enable typemaps to be compiled as either C or C++ use the JCALLx macros defined in Lib/java/javahead.swg where x is the number of arguments in the C++ version of the JNI call. The above JNI call would be written in a typemap like this
3563
To enable typemaps to be used for either C or C++ compilation, a set of JCALLx macros have been defined in Lib/java/javahead.swg,
3564
where x is the number of arguments in the C++ version of the JNI call.
3565
The above JNI calls would be written in a typemap like this
963
3567
<blockquote><pre>
964
3568
const jclass clazz = JCALL1(FindClass, jenv, "java/lang/String");
965
3569
</pre></blockquote>
968
<a name="n125"></a><h3> Name based type conversion</h3>
969
Typemaps are based both on the datatype and an optional name attached to a datatype. For example :<p>
971
<blockquote><pre>%module foo
973
// This typemap will be applied to all char ** function arguments
974
%typemap(in) char ** { ... }
976
// This typemap is applied only to char ** arguments named `argv'
977
%typemap(in) char **argv { ... }
980
In this example, two typemaps are applied to the <tt>char **</tt> datatype. However, the second typemap will only be applied to arguments named `<tt>argv</tt>'. A named typemap will always override an unnamed typemap.<p>
982
Due to the name-based nature of typemaps, it is important to note that typemaps are independent of typedef declarations. For example :<p>
984
<blockquote><pre>%typemap(in) double {
987
void foo(double); // Uses the above typemap
989
void bar(Real); // Does not use the above typemap (double != Real)
992
To get around this problem, the <tt>%apply</tt> directive can be used as follows :<p>
994
%typemap(in) double {
999
typedef double Real; // Uses typemap
1000
%apply double { Real }; // Applies all "double" typemaps to Real.
1001
void bar(Real); // Now uses the same typemap.
1004
<a name="n126"></a><h3> Converting Java String arrays to char ** </h3>
1005
A common problem in many C programs is the processing of command line arguments, which are usually passed in an array of NULL terminated strings. The following SWIG interface file allows a Java String array to be used as a <tt>char **</tt> object.<p>
3571
Note that the SWIG preprocessor expands these into the appropriate C or C++ JNI calling convention.
3572
The C calling convention is emitted by default and the C++ calling convention is emitted when using the -c++ SWIG commandline option.
3573
If you do not intend your code to be targeting both C and C++ then your typemaps can use the appropriate JNI calling convention and need not use the JCALLx macros.
3577
<a name="java_code_typemaps"></a>
3578
<a name="n62"></a><H3>17.8.7 Java code typemaps</H3>
3581
Most of SWIG's typemaps are used for the generation of C/C++ code.
3582
The typemaps in this section are used solely for the generation of Java code.
3583
Elements of proxy classes and type wrapper classes come from the following typemaps (the defaults).
3587
<tt>%typemap(javabase)</tt>
3589
base (extends) for Java class: empty default
3592
<tt>%typemap(javaclassmodifiers)</tt>
3594
class modifiers for the Java class: default is "public"
3597
<tt>%typemap(javacode)</tt>
3599
Java code is copied verbatim to the Java class: empty default
3602
<tt>%typemap(javadestruct, methodname="delete")</tt> <br>
3604
destructor wrapper - the <tt>delete()</tt> method (proxy classes only),
3605
used for all classes except those which have a base class
3606
: default calls C++ destructor (or frees C memory) and resets <tt>swigCPtr</tt> and <tt>swigCMemOwn</tt> flags
3609
Note that the <tt>delete()</tt> method name is configurable and is specified by the <tt>methodname</tt> attribute.
3612
<tt>%typemap(javadestruct_derived, methodname="delete")</tt>
3614
destructor wrapper - the <tt>delete()</tt> method (proxy classes only),
3615
same as "javadestruct" but only used for derived classes
3616
: default calls C++ destructor (or frees C memory) and resets <tt>swigCPtr</tt> and <tt>swigCMemOwn</tt> flags
3619
Note that the <tt>delete()</tt> method name is configurable and is specified by the <tt>methodname</tt> attribute.
3622
<tt>%typemap(javaimports)</tt>
3624
import statements for Java class: empty default
3627
<tt>%typemap(javainterfaces)</tt>
3629
interfaces (extends) for Java class: empty default
3632
<tt>%typemap(javafinalize)</tt>
3634
the <tt>finalize()</tt> method (proxy classes only): default calls the <tt>delete()</tt> method
3637
<tt>%typemap(javagetcptr)</tt>
3639
the <tt>getCPtr()</tt> method: default returns the <tt>swigCPtr</tt> member variable
3642
<tt>%typemap(javaptrconstructormodifiers)</tt>
3644
method modifier for the constructors taking a C pointer and the memory ownership flag: default is "protected"
3647
In summary the contents of the typemaps make up a proxy class like this:
3651
[ javaimports typemap ]
3652
[ javamodifiers typemap ] class proxyclassname extends [ javabase typemap ] implements [ javainterfaces typemap ] {
3653
[ javafinalize typemap ]
3654
[ javaptrconstructormodifiers typemap ] proxyclassname(long cPtr, boolean cMemoryOwn) {...}
3655
... Other SWIG generated constructors ...
3656
public void <i>delete</i>() [ javadestruct OR javadestruct_derived typemap ]
3657
[ javagetcptr typemap ]
3658
[ javacode typemap ]
3659
... proxy functions ...
3664
Note the <tt><i>delete</i>()</tt> methodname is configurable, see "javadestruct" and "javadestruct_derived" typemaps above.
3667
The type wrapper class is similar in construction:
3671
[ javaimports typemap ]
3672
[ javamodifiers typemap ] class typewrappername extends [ javabase typemap ] implements [ javainterfaces typemap ] {
3673
[ javaptrconstructormodifiers typemap ] proxyclassname(long cPtr, boolean bFutureUse) {...}
3674
... Other SWIG generated constructors ...
3675
[ javagetcptr typemap ]
3676
[ javacode typemap ]
3681
The defaults can be overridden to tailor these classes and are often used to hide or expose the C/C++ pointer. Here is an example which will change the <tt>getCPtr()</tt> method from the default protected access to public access.
3685
%typemap(javagetcptr) SWIGTYPE %{
3686
public static long getCPtr($javaclassname obj) {
3687
return (obj == null) ? 0 : obj.swigCPtr;
3693
Note that <tt>SWIGTYPE</tt> will target all proxy classes, but not all type wrapper classes. For the typemap to be used in all type wrapper classes, all the different types that type wrapper classes could be used for should be targeted:
3697
%typemap(javagetcptr) SWIGTYPE, SWIGTYPE *, SWIGTYPE &, SWIGTYPE [], SWIGTYPE (CLASS::*) %{
3698
public static long getCPtr($javaclassname obj) {
3699
return obj.swigCPtr;
3707
<a name="java_directors_typemaps"></a>
3708
<a name="n63"></a><H3>17.8.8 Director specific typemaps</H3>
3711
The Java directors feature requires the "javadirectorin", "javadirectorout" and the "directorin" typemaps in order to work properly.
3712
The "javapackage" typemap is an optional typemap used to identify the Java package path for individual SWIG generated proxy classes.
3715
<tt>%typemap(directorin)</tt>
3719
The "directorin" typemap is used for converting arguments in the C++ director class to the appropriate JNI type before the upcall to Java.
3720
This typemap also specifies the JNI field descriptor for the type in the "descriptor" attribute.
3721
For example, integers are converted as follows:
3725
%typemap(directorin,descriptor="I") int "$input = (jint) $1;"
3729
<code>$input</code> is the SWIG name of the JNI temporary variable passed to Java in the upcall.
3730
The <code>descriptor="I"</code> will put an <code>I</code> into the JNI field descriptor that identifies the Java method that will be called from C++.
3731
For more about JNI field descriptors and their importance, refer to the <a href="#java_typemaps">JNI documentation mentioned earlier</a>.
3732
A typemap for C character strings is:
3736
%typemap(directorin,descriptor="Ljava/lang/String;") char *
3737
%{ $input = jenv->NewStringUTF($1); %}
3742
User-defined types have the default "descriptor" attribute "<code>L$packagepath/$javaclassname;</code>" where <code>$packagepath</code>
3743
is the package name passed from the SWIG command line and <code>$javaclassname</code> is the Java proxy class' name.
3744
If the <tt>-package</tt> commandline option is not used to specify the package, then '$packagepath/' will be removed from the resulting output JNI field descriptor.
3745
<b>Do not forget the terminating ';' for JNI field descriptors starting with 'L'.</b>
3746
If the ';' is left out, Java will generate a "method not found" runtime error.
3751
<tt>%typemap(javadirectorin)</tt>
3754
Conversion from jtype to jstype for director methods.
3755
These are Java code typemaps which transform the type used in the Java intermediary JNI class (as specified in the "jtype" typemap) to
3756
the Java type used in the Java module class, proxy classes and type wrapper classes (as specified in the "jstype" typemap).
3757
This typemap provides the conversion for the parameters in the director methods when calling up from C++ to Java.
3759
For primitive types, this typemap is usually specified as:
3762
%typemap(javadirectorin) int "$jniinput"
3766
The <code>$jniinput</code> special variable is analogous to <code>$javainput</code> special variable.
3767
It is replaced by the input parameter name.
3772
<tt>%typemap(javadirectorout)</tt>
3774
Conversion from jstype to jtype for director methods.
3775
These are Java code typemaps which transform the type used in the Java module class, proxy classes and type wrapper classes (as specified in the "jstype" typemap)
3776
to the type used in the Java intermediary JNI class (as specified in the "jtype" typemap).
3777
This typemap provides the conversion for the return type in the director methods when returning from the C++ to Java upcall.
3779
For primitive types, this typemap is usually specified as:
3782
%typemap(javadirectorout) int "$javacall"
3786
The <code>$javacall</code> special variable is analogous to the <code>$jnicall</code> special variable.
3787
It is replaced by the call to the target Java method.
3788
The target method is the method in the Java proxy class which overrides the virtual C++ method in the C++ base class.
3792
<tt>%typemap(javapackage)</tt>
3796
The "javapackage" typemap is optional; it serves to identify a class's Java package.
3797
This typemap should be used in conjunction with classes that are defined outside of the current SWIG interface file.
3802
// class Foo is handled in a different interface file:
3805
%feature("director") Example;
3813
void ping(Foo *arg1, Bar *arg2);
3819
Assume that the Foo class is part of the Java package <i>wombat.foo</i> but the above interface file is part of the Java package <i>wombat.example</i>.
3820
Without the "javapackage" typemap, SWIG will assume that the Foo class belongs to <i>wombat.example</i> class.
3821
The corrected interface file looks like:
3825
// class Foo is handled in a different interface file:
3827
%typemap("javapackage") Foo "wombat.foo";
3828
%feature("director") Example;
3836
void ping(Foo *arg1, Bar *arg2);
3843
Practically speaking, you should create a separate SWIG interface file, which is %import-ed into each SWIG interface file, when you have multiple Java packages:
3847
%typemap("javapackage") SWIGTYPE, SWIGTYPE *, SWIGTYPE & "package.for.most.classes";
3849
%typemap("javapackage") Package_2_class_one "package.for.other.classes";
3850
%typemap("javapackage") Package_3_class_two "package.for.another.set";
3855
The basic strategy here is to provide a default package typemap for the majority of the classes, only providing "javapackage" typemaps for the exceptions.
3860
<a name="typemap_examples"></a>
3861
<a name="n64"></a><H2>17.9 Typemap Examples</H2>
3864
This section includes a few examples of typemaps. For more examples, you
3865
might look at the files "<tt>java.swg</tt>" and "<tt>typemaps.i</tt>" in
3869
<a name="converting_java_string_arrays"></a>
3870
<a name="n65"></a><H3>17.9.1 Converting Java String arrays to char ** </H3>
3873
A common problem in many C programs is the processing of command line arguments, which are usually passed in an array of NULL terminated strings.
3874
The following SWIG interface file allows a Java String array to be used as a <tt>char **</tt> object.<p>
1007
3876
<blockquote><pre>
1008
3877
%module example
1010
3879
/* This tells SWIG to treat char ** as a special case when used as a parameter in a function call */
1011
%typemap(in) char** (jint size) {
3880
%typemap(in) char ** (jint size) {
1013
3882
size = (*jenv)->GetArrayLength(jenv, $input);
1014
3883
$1 = (char **) malloc((size+1)*sizeof(char *));
1015
3884
/* make a copy of each string */
1016
3885
for (i = 0; i<size; i++) {
1017
3886
jstring j_string = (jstring)(*jenv)->GetObjectArrayElement(jenv, $input, i);
1018
const char* c_string = (*jenv)->GetStringUTFChars(jenv, j_string, 0);
1019
$1[i] = malloc(strlen((c_string)+1)*sizeof(const char*));
3887
const char * c_string = (*jenv)->GetStringUTFChars(jenv, j_string, 0);
3888
$1[i] = malloc(strlen((c_string)+1)*sizeof(const char *));
1020
3889
strcpy($1[i], c_string);
1021
3890
(*jenv)->ReleaseStringUTFChars(jenv, j_string, c_string);
1022
3891
(*jenv)->DeleteLocalRef(jenv, j_string);
1210
4175
</pre></blockquote>
1212
<a name="n128"></a><h3> Accessing array structure members</h3>
1214
Consider the following data structure :<p>
1223
By default, the Java module supplies the memberin typemap in the Lib/java/java_arrays file to set array members. It is generic, but not particularly efficient as it copies one array member at a time. You may want to override it for the above Data struct as follows:<p>
1226
%typemap(memberin) int[LEN] {
1227
/* Copy at most LEN characters into $1 */
1228
memcpy($1,$input,sizeof(int)*LEN);
1232
Whenever a <tt>int[LEN]</tt> type is encountered in a structure or class, this typemap provides a safe mechanism for setting its value. An alternative implementation might choose to print an error message if the Java supplied array was too long to fit into the field.<p>
1234
It should be noted that the <tt>[LEN]</tt> array size is attached to the typemap. A datatype involving some other kind of array would not be affected. However, you can write a typemap to match any sized array using the <tt>ANY</tt> keyword as follows :<p>
1237
%typemap(memberin) int [ANY] {
1238
memcpy($1,$input,sizeof(int)*$dim0);
1242
During code generation, <tt>$dim0</tt> will be filled in with the real array dimension. <p>
1244
<a name="n129"></a><h3> Pointer handling</h3>
1245
Unlike other language modules, the Java SWIG pointer library has not been written. The consequence of this is that there is no access to the SWIG runtime type checker which is used by the pointer library.
1246
This also means that your own pointer handling functions will have to be written or use some of the concepts shown in the typemap examples. The typemaps.i library file will be useful for pointer handling as previously mentioned. All is not lost as this does not apply when using shadow classes and non-primitive data types, as the section on Shadow classes demonstrates.
1249
Pointers are stored in a Java long, which is a 64 bit number. However most JVMs are 32 bit applications so any JNI code must also be compiled as 32 bit. This means that the pointers in JNI code are also 32 bits. What happens for various reasons is on big endian machines the pointer is stored in the high order 4bytes, whereas on little endian machines the pointer is stored in the low order 4bytes.
1250
As a result, care must be taken if you intend to manipulate the pointer directly from Java. This can of course can be changed with judicious use of typemaps, but normally you needn't worry about any of this unless you want to modify pointers within Java code.<p>
1252
By now you hopefully have the idea that typemaps are a powerful mechanism for building more specialized applications. While writing typemaps can be technical, many have already been written for you. See the Typemaps chapter for more information about using library files.<p>
1255
<a name="n8"></a><h2>The gory details of shadow classes</h2>
1256
This section describes the process by which SWIG creates shadow classes and some of the more subtle aspects of using them.<p>
1257
<a name="n130"></a><h3> A simple shadow class</h3>
1258
Consider the following barebones C++ class:<p>
1274
The SWIG generated class in file Simple.java looks like the following:<p>
1280
public class Simple {
1281
protected long _cPtr;
1282
protected boolean _cMemOwn;
1284
public Simple(long cPointer, boolean cMemoryOwn) {
1286
_cMemOwn = cMemoryOwn;
1289
public long getCPtr() {
1294
_cPtr = example.new_Simple();
1298
protected void finalize() {
1302
public void _delete() {
1303
if(_cPtr!=0 && _cMemOwn) {
1304
example.delete_Simple(_cPtr);
1311
<a name="n131"></a><h3> Generated class</h3>
1312
Shadow classes are built using the low-level SWIG generated C interface. The simple interface is wrapped into a Java class named after the module name, 'example' here. The Java code for the shadow class is created in many different files. The name of each file is the name of the shadow class, which in turn is named after the class/struct/union that is being shadowed (proxied). This has to be the case as in Java a class called 'A' must be in a file called A.java. Except for a couple of memory management methods and constructors, the methods in the shadow class simply call the SWIG generated functions in the simple interface. The shadow class is a lot easier to use as it wraps the C++ 'this' pointer making memory management a lot easier and less error prone. Shadow classes generally fit in with the Java programming paradigm.<p>
1314
<a name="n132"></a><h3> The this pointer</h3>
1315
Each generated shadow class has the above member variables and functions, except derived classes, which will be covered later. The <tt>_cPtr</tt> holds the pointer to an instance of the C/C++ class/struct/union, so it contains the C++ 'this' pointer. If you need the pointer it can be obtained by using the getCPtr(), as <tt>_cPtr</tt> is protected data. The shadow classes have been written with easy memory management in mind for most cases so you should normally not need to use <tt>_cPtr</tt>, nor its public accessor function getCPtr().
1318
The <tt>Grid2d</tt> class, on the other hand, is used when you want to create a new <tt>Grid2d</tt> object from Java. In reality, it inherits all of the attributes of a <tt>Grid2dPtr</tt>, except that its constructor calls the corresponding C++ constructor to create a new object. Thus, in Java, this would look something like the following :<p>
1320
<blockquote><pre>>>> g = Grid2d(50,50) # Create a new Grid2d
1321
>>> g.xpoints
1326
<a name="n133"></a><h3> Object ownership</h3>
1327
Ownership is a critical issue when mixing C++ and Java. For example, suppose I create a new object in C++, but later use it to create a Java object. If that object is being used elsewhere in the C++ code, we clearly don't want Java to delete the C++ object when the Java object is deleted. Similarly, what if I create a new object in Java, but C++ saves a pointer to it and starts using it repeatedly. Clearly, we need some notion of who owns what. Since sorting out all of the possibilities is probably impossible, the shadow class always has an attribute "<tt>_cMemOwn</tt>" that indicates whether or not Java owns an object. <p>
1329
The default object ownership falls into 2 cases:<br>
1331
<li>Whenever an object is created in Java, Java will be given ownership by setting <tt>_cMemOwn </tt> to <tt>true</tt>. </li>
1332
<li>When a Java class is created from a pre-existing SWIG generated shadow class, ownership is assumed to belong to the C/C++ code and <tt>_cMemOwn</tt> will be set to <tt>false</tt>. </li>
1334
When <tt>_cMemOwn</tt> is set, Java will attempt to call the C/C++ destructor when the object is deleted, that is garbage collected. If it is zero, Java will never call the C/C++ destructor. Ownership of an object is set up using the appropriate constructors. Note that sometimes the garbage collector does not call finalizers. Please see the section on Shadow classes and Garbage collection for more information.<p>
1336
<a name="n134"></a><h3> Constructors and destructors</h3>
1337
C++ constructors are mapped into an equivalent Java constructor. An additional constructor is available for use which overrides the default memory handling/memory ownership. For the above example, this constructor is shown as:
1339
public Simple(long cPointer, boolean cMemoryOwn) {
1341
_cMemOwn = cMemoryOwn;
1344
It allows one to override the above default <tt>_cPtr</tt> and <tt>_cMemOwn</tt> values on construction.<p>
1346
The <tt>finalize()</tt> method is generated by default, but it can be turned off using the -nofinalize commandline option. It calls the <tt>_delete()</tt> method which calls the C++ destructor only if the Java object owns the C++ memory.
1348
If there is no C++ default constructor, a default constructor is required by Java and so a protected constructor is generated as follows:
1350
protected Simple() {
1355
It is highly recommended to use the %make_default directive in your interface file so that SWIG generates default constructors and destructors if none exist. This is useful as these do not exist if you are using C. Note that when using C++ the compiler generates a default constructor and destructor for you if none exist, so this is different to SWIG's default behaviour.
1357
Note that SWIG currently does not support method overloading and thus constructor overloading, but this is likely to change in a future release.
1359
<a name="n135"></a><h3> Member data</h3>
1360
Member data of a C/C++ object is accessed through getter and setter methods. For example, if a public member variable and a public static member variable is added to the previous bare bones class as such:<p>
1367
static int StaticNumber;
1370
The class can be used as follows to read and write to the variables:
1372
Simple simp = new Simple();
1374
int number = simp.getNumber();
1376
Simple.setStaticNumber(10);
1377
number = Simple.getStaticNumber();
1379
Note that the C++ static member variable is mapped using Java static getters and setters.
1381
<a name="n136"></a><h3> Shadow Functions</h3>
1382
Suppose you have the following declarations in an interface file :<p>
1390
static Vector addv(Vector a, Vector b);
1393
By default in the simple SWIG interface, the function <tt>addv</tt> will operate on Vector pointers (a Java long), not Java classes:
1396
// Member function in class example (SWIG's simple interface)
1397
public final static native long Vector_addv(long jarg0, long jarg1);
1400
However, when using shadow classes, the Java SWIG module is smart enough to know that <tt>Vector</tt> has been wrapped into a Java class so it will create the following shadow function for the <tt>addv()</tt> function.<p>
1403
// Member function in class Vector (the shadow class)
1404
public static Vector addv(Vector a, Vector b) {
1405
return new Vector(example.Vector_addv(a.getCPtr(), b.getCPtr()), true);
1409
Function arguments are modified to pick up the "this" pointer from a Java Vector object. The return value is a pointer to the result which has been allocated by malloc or new (this behavior is described in the chapter on SWIG basics), so we simply create a new Vector class with the return value. Since the result involved an implicit malloc, we set the ownership to <tt>true</tt> indicating that the result is to be owned by Java and that it should be deleted when the Java object is deleted. As a result, operations like this are perfectly legal and result in no memory leaks:<p>
1412
Vector v = Vector.addv(Vector.addv(Vector.addv(Vector.addv(a,b),c),d),e);
1415
<a name="n137"></a><h3> Shadow class pointer handling</h3>
1416
Now let's take the previous example and in a new function <tt>cross_product</tt> and use Vector pointers for the parameters as well as the return type:
1424
static Vector addv(Vector a, Vector b);
1425
static Vector *cross_product(Vector *v1, Vector *v2);
1428
By default in the simple SWIG interface, the function <tt>cross_product</tt> will also operate on Vector pointers (a Java long):
1431
// Member function in class example (SWIG's simple interface)
1432
public final static native long Vector_cross_product(long jarg0, long jarg1);
1435
When using shadow classes, the Java SWIG module still allows us to use a <tt>Vector</tt> proper:
1437
// Member function in class Vector (the shadow class)
1438
public static Vector cross_product(Vector v1, Vector v2) {
1439
return new Vector(example.Vector_cross_product(v1.getCPtr(), v2.getCPtr()), false);
1444
The shadow function gets the pointer for us from the Vector class. Note that the return value is a Vector whose memory ownership is set to <tt>false</tt> indicating that the memory is not owned by Java. The following section discusses this further.<p>
1446
An important observation to note when using shadow classes is the differences in wrapping pointers to complex datatypes and pointers to primitive types. Pointers to complex data types are wrapped using a Java class, such as Vector for Vector*. Pointers to primitive types are wrapped in the same manner as the simple interface, that is a Java long for short*, int* etc.<p>
1448
<a name="n138"></a><h3> Methods that return new objects</h3>
1449
By default SWIG assumes that constructors are the only functions returning new objects to Java. However, you may have other functions that return new objects as well. If we take our previous Vector example and examine the <tt>cross_product</tt> implementation:<p>
1451
Vector *Vector::cross_product(Vector *v1, Vector *v2) {
1452
Vector *result = new Vector();
1453
result = ... compute cross product ...
1457
When the value is returned to Java, we want Java to assume ownership as the memory has been created on the heap. However, SWIG has no way of knowing that it should take ownership, so by default it does not. The memory has to be deleted after calling the cross_product function:<p>
1460
Vector a = new Vector();
1461
Vector b = new Vector();
1462
// ... populate a and b ...
1464
Vector c = Vector.cross_product(a, b);
1466
// clean up the memory allocated by cross_product
1467
example.delete_Vector(c.getCPtr());
1470
Unfortunately, this is ugly, is likely to be forgotten and it doesn't work if we use the result as a temporary value :<p>
1473
Vector w = Vector.addv(Vector.cross_product(a,b),c); // Results in a memory leak
1475
However, you can provide a hint to SWIG when working with such a function as shown :<p>
1478
// C/C++ Function returning a new object
1481
%new static Vector *cross_product(Vector *v1, Vector *v2);
1485
The <tt>%new</tt> directive provides a hint that the function is returning a new object. The Java module will assign proper ownership of the object when this is used. This can be seen as this time it uses <tt>true</tt> in the constructor:<p>
1488
// Member function in class Vector (the shadow class)
1489
public static Vector cross_product(Vector v1, Vector v2) {
1490
return new Vector(example.Vector_cross_product(v1.getCPtr(), v2.getCPtr()), true);
1494
<a name="n139"></a><h3> Global variables and functions</h3>
1495
Substitution of complex datatypes occurs for all shadow functions and shadow member functions involving structures, unions or class definitions. Currently no shadow classes are produced for global variables nor global functions. Only the low-level C interface is produced. This is an important limitation. The recommended approach is to put all global access into a dummy structure with static function access:<p>
1499
%pragma make_default
1506
static Vector addv(Vector a, Vector b);
1509
// Global function and variable
1510
Vector global_subv(Vector a, Vector b);
1513
// Global function and variable wrapped into this structure
1515
static Vector sub1(Vector a, Vector b) { return global_subv(a, b); };
1516
static void setGlobal_vec(Vector v) { global_vec = v; };
1517
static Vector getGlobal_vec(void) { return global_vec; };
1521
// Alternative way to wrap global functions into a structure
1522
%addmethods Globals { static Vector sub2(Vector a, Vector b) { return global_subv(a, b); }
1524
The dummy class consists entirely of static member functions. Note the two different ways that global_subv can be wrapped into Globals. Access to the global function <tt>global_subv</tt> is then much neater:
1527
Vector a = new Vector();
1528
Vector b = new Vector();
1529
// ... setup a and b ...
1531
// Access to global function which has been wrapped into the Globals shadow class
1532
Vector c1 = Globals.sub1(a,b);
1533
Vector c2 = Globals.sub2(a,b);
1535
// Access to global function using simple interface
1536
Vector c3 = new Vector(example.global_subv(a.getCPtr(), b.getCPtr()), true);
1539
This is one area where the Java module needs improving in the future so that all global functions are for instance automatically accessible through a shadow class.<p>
1541
<a name="n140"></a><h3> Nested objects</h3>
1542
SWIG shadow classes support nesting of complex objects. For example, suppose you had the following interface file :<p>
1546
%pragma make_default
1552
static Vector addv(Vector a, Vector b);
1565
In this case you will be able to read and write to members as follows :<p>
1568
Vector v1 = new Vector();
1569
Vector v2 = new Vector();
1570
// ... populate v1 and v2 ...
1572
Particle p = new Particle();
1574
p.getR().setY(-1.5);
1576
p.setV( Vector.addv(v1, v2) );
1579
Nested structures such as the following are also supported by SWIG. These types of structures tend to arise frequently in database and information processing applications.<p>
1583
unsigned int dataType;
1600
Access is provided like this:<p>
1603
ValueStruct v = new ValueStruct();
1604
// ... populate ValueStruct somehow ...
1606
long dataType = v.getDataType();
1607
int intval = v.getU().getIntval();
1608
double f = v.getU().getV().getF();
1611
To support the embedded structure definitions, SWIG has to extract the internal structure definitions and use them to create new Java classes. In this example, the following shadow classes are created:<p>
1614
//Class corresponding to union u member
1615
ValueStruct_u u = v.getU();
1617
//Class corresponding to struct v member of union u
1618
ValueStruct_u_v uv = v.getU().getV();
1621
The names of the new classes are formed by appending the member names of each embedded structure.<p>
1623
<a name="n141"></a><h3> Inheritance and shadow classes</h3>
1624
Since shadow classes are implemented in Java, you can use any of the automatically generated classes as a base class for more Java classes.<p>
1626
SWIG can detect C++ classes that are abstract. This means that the Java shadow class can accurately shadow the C++ class. For example, given the abstract base class Shape and its derived class Circle:
1634
void move(double dx, double dy);
1635
virtual double area() = 0;
1638
class Circle : public Shape {
1642
Circle(double r) : radius(r) { };
1643
virtual double area();
1647
The Shape shadow class becomes an abstract Java class with the pure virtual function <tt>area</tt> being declared as a Java abstract method. The constructor is also made protected:
1653
public abstract class Shape {
1654
protected long _cPtr;
1655
protected boolean _cMemOwn;
1657
public Shape(long cPointer, boolean cMemoryOwn) {
1659
_cMemOwn = cMemoryOwn;
1662
public long getCPtr() {
1671
protected void finalize() {
1675
public void _delete() {
1676
if(_cPtr!=0 && _cMemOwn) {
1677
example.delete_Shape(_cPtr);
1682
public void move(double dx, double dy) {
1683
example.Shape_move(_cPtr, dx, dy);
1686
public abstract double area();
1691
The Circle class extends Shape mirroring the C++ class inheritance hierarchy.
1697
public class Circle extends Shape {
1698
public Circle(long cPointer, boolean cMemoryOwn) {
1699
super(cPointer, cMemoryOwn);
1702
protected Circle() {
1705
public Circle(double r) {
1707
_cPtr = example.new_Circle(r);
1709
// The above will be optimised in the future to:
1710
// super(example.new_Circle(r), true);
1713
public double area() {
1714
return example.Circle_area(_cPtr);
1719
It is then of course possible to extend Shape using your own Java classes. If say <tt>Circle</tt> is provided by the C++ code, you could for example add in a pure Java class <tt>Rectangle</tt>. There is a caveat and that is any C++ code will not know about your Java class <tt>Rectangle</tt> so this type of derivation is restricted.<p>
1721
Note that Java does not support multiple inheritance so any multiple inheritance in the C++ code is not going to work. A warning is given when multiple inheritance is detected and only the first base class is used.
1723
<a name="n142"></a><h3>Shadow classes and garbage collection</h3>
1724
If you get SWIG to produce shadow classes, you will notice the generated <code>_delete()</code> and <code>finalize()</code> methods. The <code>finalize()</code> method calls <code>_delete()</code> which frees any SWIG malloced c memory for wrapped structs or deletes any SWIG wrapped classes created on the heap, which in turn calls the class' destructor. The idea is for <code>_delete()</code> to be called when you have finished with the C/C++ object. Ideally you need not call <code>_delete()</code>, but rather leave it to the garbage collector to call it from the finalizer. The unfortunate thing is that Sun, in their wisdom, do not guarantee that the finalizers will be called. When a program exits, the garbage collector does not always call the finalizers. Depending on what the finalizers do and which operating system you use, this may or may not be a problem.
1727
If the <code>_delete()</code> call into JNI code is just for memory handling, there is not a problem when run on Windows and Unix. Say your JNI code creates memory on the heap which your finalizers will clean up, the finalizers may or may not be called before the program exits. In Windows and Unix all memory that a process uses is returned to the system, so this isn't a problem. This is not the case in some operating systems like vxWorks. If however, your finalizer calls into JNI code invoking the C++ destructor which in turn releases a TCP/IP socket for example, there is no guarantee that it will be released. Note that the garbage collector will eventually run, so long running programs will have their unreferenced object's finalizers called.
1730
Some not so ideal solutions are:
1733
Call the <code>System.runFinalizersOnExit(true)</code> or <code>Runtime.getRuntime().runFinalizersOnExit(true)</code> to ensure the finalizers are called before the program exits. The catch is that this is a deprecated function call as the documenation says:
1735
This method is inherently unsafe. It may result in finalizers being called on live objects while other threads are concurrently manipulating those objects, resulting in erratic behavior or deadlock.
1737
In many cases you will be lucky and find that it works, but it is not to be advocated. Have a look at <a href=http://java.sun.com>Sun's Java web site</a> and search for <code>runFinalizersOnExit</code>.
1741
From jdk1.3 onwards a new function, <code>addShutdownHook()</code>, was introduced which is guaranteed to be called when your program exits. You can encourage the garbage collector to call the finalizers, for example, add this static block to the class that has the <code>main()</code> function:
1744
Runtime.getRuntime().addShutdownHook(
1746
public void run() { System.gc(); System.runFinalization(); }
1751
Although this usually works, the documentation doesn't guarantee that <code>runFinalization()</code> will actually call the finalizers. As the the shutdown hook is guaranteed you could also make a JNI call to clean up any resources that are being tracked by the C/C++ code.
1755
Call the <code>_delete()</code> function manually. As a suggestion it may be a good idea to set the object to null so that should the object be inadvertantly used again a Java null pointer exception is thrown, the alternative would crash the JVM by using a null c pointer. For example given a SWIG generated class A:
1760
// any use of myA here would crash the JVM
1762
// any use of myA here would cause a Java null pointer exception to be thrown
1764
The SWIG generated code ensures that the memory is not deleted twice, in the event the finalizers get called in addition to the manual <code>_delete()</code> call.
1769
Write your own object manager in Java. You could derive all SWIG classes from a single base class which could track which objects have had their finalizers run, then call the rest of them on program termination. Currently you cannot tell SWIG to derive a SWIG shadow class from any named Java class, but this is planned in the near future. An alternative is to add the object handling code to all generated shadow classes using the shadow pragma.
1773
<a name="n143"></a><h3> Performance concerns and hints</h3>
1774
Shadow classing is primarily intended to be a convenient way of accessing C/C++ objects from Java. However, if you're directly manipulating huge arrays of complex objects from Java, performance may suffer greatly. In these cases, you should consider implementing the functions in C or thinking of ways to optimize the problem. Try and minimise the expensive JNI calls to C/C++ functions, perhaps by using temporary Java variables instead of accessing the information directly from the C/C++ object.<p>
1777
If performance is really critical you can use the low-level interface which eliminates all of the overhead of going through the shadow classes (at the expense of coding simplicity).<p>
1781
<a name="n9"></a><h2>Java pragmas</h2>
1782
There are two groups of pragmas in the Java module. The first group modify the Java module output file and the second modify the Java shadow output file. The pragmas beginning with <b>module</b> apply to the module output file. The pragmas beginning with <b>allshadow</b> apply to all shadow output classes. The pragmas beginning with <b>shadow</b> apply to the currently active shadow class so these pragmas can only be specified within the definition of a class or struct. Some examples:
1786
%pragma(java) modulecode=%{ /*This code gets added to the module class*/ %}
1787
%pragma(java) modulecode=%{ /*This code gets added to the module class*/ %}
1788
%pragma(java) allshadowcode=%{ /*This code gets added to every shadow class*/ %}
1790
typedef struct TestStruct {
1792
%pragma(java) shadowcode=%{ /*This code gets added to the TestStruct shadow class only*/ %}
1798
Note that pragmas will take either " " or %{ %} as delimeters. If the pragma requires the string quote it must be preceded with a backslash or alternatively use the %{ %} delimeters, for example either of these can be used to obtain the desired effect:
1801
%pragma(java) modulecode= " public void sayHello() { System.out.println(\"Hello\"); } "
1802
%pragma(java) modulecode=%{ public void sayHello() { System.out.println("Hello"); } %}
1806
A complete list of pragmas follows:
1810
<td><b>Pragma</b></td>
1811
<td><b>Description</b></td>
1812
<td><b>Example</b></td>
1816
<td>Specifies a base class for the Java module class.</td>
1817
<td>%pragma(java) modulebase="BaseClass"</td>
1821
<td>Specifies a base class for the Java shadow class.</td>
1822
<td>%pragma(java) shadowbase="BaseClass"</td>
1825
<td>allshadowbase</td>
1826
<td>Specifies a base class for all Java shadow classes.</td>
1827
<td>%pragma(java) allshadowbase="BaseClass"</td>
1831
<td>Adds code to the Java module class.</td>
1832
<td>%pragma(java) modulecode=%{/*module code*/%}</td>
1836
<td>Adds code to the Java shadow class. See the JavaDoc section below about using this pragma for JavaDoc comments.</td>
1837
<td>%pragma(java) shadowcode=%{/*shadow code*/%}</td>
1840
<td>allshadowcode</td>
1841
<td>Adds code to all Java classes.</td>
1842
<td>%pragma(java) allshadowcode=%{/*all shadow code*/%}</td>
1845
<td>moduleclassmodifiers</td>
1846
<td>Overrides the default Java module class modifiers. The default is public.</td>
1847
<td>%pragma(java) moduleclassmodifiers="public final"</td>
1850
<td>shadowclassmodifiers</td>
1851
<td>Overrides the default Java shadow class modifiers. The default is public. Also overrides allshadowclassmodifiers if present.</td>
1852
<td>%pragma(java) shadowclassmodifiers="public final"</td>
1855
<td>allshadowclassmodifiers</td>
1856
<td>Overrides the default modifiers for all Java classes. The default is public.</td>
1857
<td>%pragma(java) allshadowclassmodifiers="public final"</td>
1860
<td>moduleimport</td>
1861
<td>Adds an import statement to the Java module class file.</td>
1862
<td>%pragma(java) moduleimport="java.lang.*"</td>
1865
<td>shadowimport</td>
1866
<td>Adds an import statement to the Java shadow class file. Adds to any imports specified in allshadowimport.</td>
1867
<td>%pragma(java) shadowimport="java.lang.*"</td>
1870
<td>allshadowimport</td>
1871
<td>Adds an import statement to all Java shadow class files.</td>
1872
<td>%pragma(java) allshadowimport="java.lang.*"</td>
1875
<td>moduleinterface</td>
1876
<td>Specifies an interface which the Java module output class implements. Can be used multiple times as Java supports multiple interfaces.</td>
1877
<td>%pragma(java) moduleinterface="SomeInterface"</td>
1880
<td>shadowinterface</td>
1881
<td>Specifies an interface which the Java shadow class implements. Can be used multiple times as Java supports multiple interfaces. Adds to any interfaces specified in allshadowinterface.</td>
1882
<td>%pragma(java) shadowinterface="SomeInterface"</td>
1885
<td>allshadowinterface</td>
1886
<td>Specifies an interface which all Java shadow classes implement. Can be used multiple times as Java supports multiple interfaces.</td>
1887
<td>%pragma(java) allshadowinterface="SomeInterface"</td>
1890
<td>modulemethodmodifiers</td>
1891
<td>Overrides the native default method modifiers for the module class. The default is public final static.</td>
1892
<td>%pragma(java) modulemethodmodifiers="protected final static synchronized"</td>
1898
<a name="n144"></a><h3> Deprecated pragmas</h3>
1899
The following pragmas were in Swig 1.3a3 and have since been deprecated:<br>
1900
<b>import</b>: Please replace with <b>moduleimport</b>, <b>shadowimport</b> and/or <b>allshadowimport</b> pragmas.<br>
1901
<b>module</b>: Please replace with the <b>modulecode</b> pragma.<br>
1902
<b>shadow</b>: Please replace with the <b>allshadowcode</b> pragma.<br>
1903
<b>modifiers</b>: Please replace with the <b>modulemethodmodifiers</b> pragma.<br>
1905
<a name="n145"></a><h3> Pragma uses</h3>
1906
The pragmas are used primarily to modify the default Java output code. They provide flexibility as to how Java and C++ interact. In the pragma notation below, <b>xxxcode</b> for example would be used to denote the 3 similar 'code' pragmas, that is <b>modulecode</b>, <b>shadowcode</b> and <b>allshadowcode</b>.
1908
<h4> Derive C++ from Java and visa-versa</h4>
1909
It is possible to derive a Java class from a shadow class (i.e. a C++ class) with the Java module. However, with the pragmas it is also possible to derive the SWIG produced Java shadow classes (i.e. C++ class) from your own Java class by using the <b>xxxbase</b> pragma with the <b>xxximport</b>, <b>xxxcode</b> and <b>xxxclassmodifiers</b> pragmas. It is also possible for the SWIG produced Java classes to implement interfaces using the <b>xxxinterface</b> pragmas.
1911
<h4> JavaDoc and the shadowcode pragma</h4>
1912
The SWIG documentation feature is not currently present in the 1.3 versions of SWIG. However a limited form of JavaDoc documentation can be implemented by placing JavaDoc comments in the <b>shadowcode</b> pragma. Just put your JavaDoc comment in a <b>shadowcode</b> pragma before the function to which you want it to apply.
1914
<h4> Tips for using the shadow pragmas</h4>
1915
Note that an out of scope warning is issued if any of the <b>shadow</b> pragmas are used outside of the class/struct/union definition. This requires one of these pragmas to be placed within the definition of the class/struct/union. It may seem that the original C/C++ code has to be modified when using the <tt>%include</tt> pragma. A technique to avoid this is to place the pragma within the <tt>%addmethods</tt> directive. For example:
4177
<a name="adding_downcasts"></a>
4178
<a name="n68"></a><H3>17.9.4 Adding Java downcasts to polymorphic return types</H3>
4181
SWIG support for polymorphism works in that the appropriate virtual function is called. However, the default generated code does not allow for downcasting.
4182
Let's examine this with the follow code:
4185
%include "std_string.i"
4187
#include <iostream>
4188
using namespace std;
4191
virtual void start() = 0;
4195
class Ambulance : public Vehicle {
4198
Ambulance(string volume) : vol(volume) {}
4199
virtual void start() {
4200
cout << "Ambulance started" << endl;
4202
void sound_siren() {
4203
cout << vol << " siren sounded!" << endl;
4208
Vehicle *vehicle_factory() {
4209
return new Ambulance("Very loud");
4213
If we execute the following Java code:
4216
Vehicle vehicle = example.vehicle_factory();
4219
Ambulance ambulance = (Ambulance)vehicle;
4220
ambulance.sound_siren();
4227
java.lang.ClassCastException
4228
at main.main(main.java:16)
4231
Even though we know from examination of the C++ code that <tt>vehicle_factory</tt> returns an object of type <tt>Ambulance</tt>,
4232
we are not able to use this knowledge to perform the downcast in Java.
4233
This occurs because the runtime type information is not completely passed from C++ to Java when returning the type from <tt>vehicle_factory()</tt>.
4234
Usually this is not a problem as virtual functions do work by default, such as in the case of <tt>start()</tt>.
4235
There are a few solutions to getting downcasts to work.
4238
The first is not to use a Java cast but a call to C++ to make the cast. Add this to your code:
4240
%exception Ambulance::dynamic_cast(Vehicle *vehicle) {
4243
jclass excep = jenv->FindClass("java/lang/ClassCastException");
4245
jenv->ThrowNew(excep, "dynamic_cast exception");
4250
static Ambulance *dynamic_cast(Vehicle *vehicle) {
4251
return dynamic_cast<Ambulance *>(vehicle);
4256
It would then be used from Java like this
4259
Ambulance ambulance = Ambulance.dynamic_cast(vehicle);
4260
ambulance.sound_siren();
4262
Should <tt>vehicle</tt> not be of type <tt>ambulance</tt> then a Java <tt>ClassCastException</tt> is thrown.
4263
The next solution is a purer solution in that Java downcasts can be performed on the types.
4264
Add the following before the definition of <tt>vehicle_factory</tt>:
4267
%typemap(out) Vehicle * {
4268
Ambulance *downcast = dynamic_cast<Ambulance *>($1);
4269
*(Ambulance **)&$result = downcast;
4272
%typemap(javaout) Vehicle * {
4273
return new Ambulance($jnicall, $owner);
4277
Here we are using our knowledge that <tt>vehicle_factory</tt> always returns type <tt>Ambulance</tt> so that the Java proxy is created as a type <tt>Ambulance</tt>.
4278
If <tt>vehicle_factory</tt> can manufacture any type of <tt>Vehicle</tt> and we want to be able to downcast using Java casts for any of these types, then a different approach is needed.
4279
Consider expanding our example with a new Vehicle type and a more flexible factory function:
4282
class FireEngine : public Vehicle {
4285
virtual void start() {
4286
cout << "FireEngine started" << endl;
4288
void roll_out_hose() {
4289
cout << "Hose rolled out" << endl;
4293
Vehicle *vehicle_factory(int vehicle_number) {
4294
if (vehicle_number == 0)
4295
return new Ambulance("Very loud");
4297
return new FireEngine();
4301
To be able to downcast with this sort of Java code:
4304
FireEngine fireengine = (FireEngine)example.vehicle_factory(1);
4305
fireengine.roll_out_hose();
4306
Ambulance ambulance = (Ambulance)example.vehicle_factory(0);
4307
ambulance.sound_siren();
4310
the following typemaps targeted at the <tt>vehicle_factory</tt> function will achieve this.
4311
Note that in this case, the Java class is constructed using JNI code rather than passing a pointer across the JNI boundary in a Java long for construction in Java code.
4314
%typemap(jni) Vehicle *vehicle_factory "jobject"
4315
%typemap(jtype) Vehicle *vehicle_factory "Vehicle"
4316
%typemap(jstype) Vehicle *vehicle_factory "Vehicle"
4317
%typemap(javaout) Vehicle *vehicle_factory {
4321
%typemap(out) Vehicle *vehicle_factory {
4322
Ambulance *ambulance = dynamic_cast<Ambulance *>($1);
4323
FireEngine *fireengine = dynamic_cast<FireEngine *>($1);
4325
// call the Ambulance(long cPtr, boolean cMemoryOwn) constructor
4326
jclass clazz = jenv->FindClass("Ambulance");
4328
jmethodID mid = jenv->GetMethodID(clazz, "<init>", "(JZ)V");
4331
*(Ambulance **)&cptr = ambulance;
4332
$result = jenv->NewObject(clazz, mid, cptr, false);
4335
} else if (fireengine) {
4336
// call the FireEngine(long cPtr, boolean cMemoryOwn) constructor
4337
jclass clazz = jenv->FindClass("FireEngine");
4339
jmethodID mid = jenv->GetMethodID(clazz, "<init>", "(JZ)V");
4342
*(FireEngine **)&cptr = fireengine;
4343
$result = jenv->NewObject(clazz, mid, cptr, false);
4348
cout << "Unexpected type " << endl;
4352
cout << "Failed to create new java object" << endl;
4356
Better error handling would need to be added into this code.
4357
There are other solutions to this problem, but this last example demonstrates some more involved JNI code.
4358
SWIG usually generates code which constructs the proxy classes using Java code as it is easier to handle error conditions and is faster.
4359
Note that the JNI code above uses a number of string lookups to call a constructor, whereas this would not occur using byte compiled Java code.
4361
<a name="adding_equals_method"></a>
4362
<a name="n69"></a><H3>17.9.5 Adding an equals method to the Java classes</H3>
4365
When a pointer is returned from a JNI function, it is wrapped using a new Java proxy class or type wrapper class.
4366
Even when the pointers are the same, it will not be possible to know that the two Java classes containing those pointers are actually the same object.
4367
It is common in Java to use the <tt>equals()</tt> method to check whether two objects are equivalent.
4368
An equals method is easily added to all proxy classes. For example:
4372
%typemap(javacode) SWIGTYPE %{
4373
public boolean equals(Object obj) {
4374
boolean equal = false;
4375
if (obj instanceof $javaclassname)
4376
equal = ((($javaclassname)obj).swigCPtr == this.swigCPtr);
4382
Foo* returnFoo(Foo *foo) { return foo; }
4386
The following would display <tt>false</tt> without the <tt>javacode</tt> typemap above. With the typemap defining the <tt>equals</tt> method the result is <tt>true</tt>.
4390
Foo foo1 = new Foo();
4391
Foo foo2 = example.returnFoo(foo1);
4392
System.out.println("foo1? " + foo1.equals(foo2));
4397
<a name="void_pointers"></a>
4398
<a name="n70"></a><H3>17.9.6 Void pointers and a common Java base class</H3>
4401
One might wonder why the common code that SWIG emits for the proxy and type wrapper classes is not pushed into a base class.
4402
The reason is that although <tt>swigCPtr</tt> could be put into a common base class for all classes
4403
wrapping C structures, it would not work for C++ classes involved in an inheritance chain.
4404
Each class derived from a base needs a separate <tt>swigCPtr</tt> because C++ compilers sometimes use a different pointer value when casting a derived class to a base.
4405
Additionally as Java only supports single inheritance, it would not be possible to derive wrapped classes from your own pure Java classes if the base class has been 'used up' by SWIG.
4406
However, you may want to move some of the common code into a base class.
4407
Here is an example which uses a common base class for all proxy classes and type wrapper classes:
4411
%typemap(javabase) SWIGTYPE, SWIGTYPE *, SWIGTYPE &, SWIGTYPE [], SWIGTYPE (CLASS::*) "SWIG"
4413
%typemap(javacode) SWIGTYPE, SWIGTYPE *, SWIGTYPE &, SWIGTYPE [], SWIGTYPE (CLASS::*) %{
4414
protected long getPointer() {
4422
Define new base class called SWIG:
4426
public abstract class SWIG {
4427
protected abstract long getPointer();
4429
public boolean equals(Object obj) {
4430
boolean equal = false;
4431
if (obj instanceof SWIG)
4432
equal = (((SWIG)obj).getPointer() == this.getPointer());
4436
SWIGTYPE_p_void getVoidPointer() {
4437
return new SWIGTYPE_p_void(getPointer(), false);
4443
This example contains some useful functionality which you may want in your code.
4445
<li> It has an <tt>equals()</tt> method. Unlike the previous example, the method code isn't replicated in all classes.
4446
<li> It also has a function which effectively implements a cast from the type of the proxy/type wrapper class to a void pointer. This is necessary for passing a proxy class or a type wrapper class to a function that takes a void pointer.
4449
<a name="java_directors_faq"></a>
4450
<a name="n71"></a><H2>17.10 Living with Java Directors</H2>
4454
This section is intended to address frequently asked questions and frequently encountered problems when using Java directors.
4457
<li><i>When my program starts up, it complains that </i>method_foo<i> cannot
4458
be found in a Java method called </i>swig_module_init<i>. How do I fix
4462
Open up the C++ wrapper source code file and look for <code>"method_foo"</code> (include the double quotes, they are important!)
4463
Look at the JNI field descriptor and make sure that each class that occurs in the descriptor has the correct package name in front of it.
4464
If the package name is incorrect, put a "javapackage" typemap in your SWIG interface file.
4467
<li><i>I'm compiling my code and I'm using templates. I provided a
4468
javapackage typemap, but SWIG doesn't generate the right JNI field
4469
descriptor.</i></li>
4471
Use the template's renamed name as the argument to the "javapackage" typemap:
4475
%typemap(javapackage) std::vector<int> "your.package.here"
4476
%template(VectorOfInt) std::vector<int>;
4481
<li><i>When I pass class pointers or references through a C++ upcall and I
4482
try to type cast them, Java complains with a ClassCastException. What am I
4483
doing wrong?</i></li>
4485
Normally, a non-director generated Java proxy class creates temporary Java objects as follows:
4488
public static void MyClass_method_upcall(MyClass self, long jarg1)
4490
Foo darg1 = new Foo(jarg1, false);
4492
self.method_upcall(darg1);
4497
Unfortunately, this loses the Java type information that is part of the underlying Foo director proxy class's java object pointer causing the type cast to fail.
4498
The SWIG Java module's director code attempts to correct the problem, <b>but only for director-enabled classes</b>, since the director class retains a global reference to its Java object.
4499
Thus, for director-enabled classes <b>and only for director-enabled classes</b>, the generated proxy Java code looks somthing like:
4503
public static void MyClass_method_upcall(MyClass self, long jarg1, Foo jarg1_object)
4505
Foo darg1 = (jarg1_object != null ? jarg1_object : new Foo(jarg1, false));
4507
self.method_upcall(darg1);
4512
When you import a SWIG interface file containing class definitions, the classes you want to be director-enabled must be have the <code>feature("director")</code> enabled for type symmetry to work.
4513
This applies even when the class being wrapped isn't a director-enabled class but takes parameters that are director-enabled classes.
4516
The current "type symmetry" design will work for simple C++ inheritance, but will most likely fail for anything more compicated such as tree or diamond C++ inheritance hierarchies.
4517
Those who are interested in challenging problems are more than welcome to hack the <code>Java::Java_director_declaration</code> method in <code>Source/Modules/java.cxx</code>.
4520
If all else fails, you can use the downcastXXXXX() method to attempt to recover the director class's Java object pointer.
4521
For the Java Foo proxy class, the Foo director class's java object pointer can be accessed through the javaObjectFoo() method.
4522
The generated method's signature is:
4526
public static Foo javaObjectFoo(Foo obj);
4530
From your code, this method is invoked as follows:
4534
public class MyClassDerived {
4535
public void method_upcall(Foo foo_object)
4537
FooDerived derived = (foo_object != null ? (FooDerived) Foo.downcastFoo(foo_object) : null);
4538
/* rest of your code here */
4544
An good approach for managing downcasting is placing a static method in each derived class that performs the downcast from the superclass, e.g.,
4547
public class FooDerived extends Foo {
4549
public static FooDerived downcastFooDerived(Foo foo_object)
4552
return (foo_object != null ? (FooDerived) Foo.downcastFoo(foo_object);
4555
catch (ClassCastException exc) {
4556
// Wasn't a FooDerived object, some other sublcass of Foo
4564
Then change the code in MyClassDerived as follows:
4568
public class MyClassDerived extends MyClass {
4570
public void method_upcall(Foo foo_object)
4572
FooDerived derived = FooDerived.downcastFooDerived(foo_object) : null);
4573
/* rest of your code here */
4581
<li><i>Why isn't the proxy class declared abstract? Why aren't the director
4582
upcall methods in the proxy class declared abstract?</i></li>
4584
Declaring the proxy class and its methods abstract would break the JNI argument marshalling and SWIG's downcall functionality (going from Java to C++.)
4585
Create an abstract Java subclass that inherits from the director-enabled class instead.
4586
Using the previous Foo class example:
4590
public abstract class UserVisibleFoo extends Foo {
4591
/** Make sure user overrides this method, it's where the upcall
4594
public abstract void method_upcall(Foo foo_object);
4596
/// Downcast from Foo to UserVisibleFoo
4597
public static UserVisibleFoo downcastUserVisibleFoo(Foo foo_object)
4600
return (foo_object != null ? (FooDerived) Foo.downcastFoo(foo_object) : null);
4603
catch (ClassCastException exc) {
4604
// Wasn't a FooDerived object, some other sublcass of Foo
4611
This doesn't prevent the user from creating subclasses derived from Foo, however, UserVisibleFoo provides the safety net that reminds the user to override the <code>method_upcall()</code> method.
4615
<a name="odds_ends"></a>
4616
<a name="n72"></a><H2>17.11 Odds and ends</H2>
4619
<a name="javadoc_comments"></a>
4620
<a name="n73"></a><H3>17.11.1 JavaDoc comments</H3>
4623
The SWIG documentation system is currently deprecated.
4624
When it is resurrected JavaDoc comments will be fully supported.
4625
If you can't wait for the full documentation system a couple of workarounds are available.
4626
The <tt>%javamethodmodifiers</tt> feature can be used for adding proxy class method comments and module class method comments.
4627
The "javaimports" typemap can be hijacked for adding in proxy class JavaDoc comments.
4628
The <tt>jniclassimports</tt> or <tt>jniclassclassmodifiers</tt> pragmas can also be used for adding intermediary JNI class comments and likewise the <tt>moduleimports</tt> or <tt>moduleclassmodifiers</tt> pragmas for the module class.
4629
Here is an example adding in a proxy class and method comment:
4633
%javamethodmodifiers Barmy::lose_marbles() "
4635
* Calling this method will make you mad.
4636
* Use with <b>utmost</b> caution.
4640
%typemap(javaimports) Barmy "
4641
/** The crazy class. Use as a last resort. */"
4645
void lose_marbles() {}
4650
Note the "public" added at the end of the <tt>%javamethodmodifiers</tt> as this is the default for this feature.
4651
The generated proxy class with JavaDoc comments is then as follows:
4654
/** The crazy class. Use as a last resort. */
4655
public class Barmy {
4658
* Calling this method will make you mad.
4659
* Use with <b>utmost</b> caution.
4661
public void lose_marbles() {
4671
<a name="functional_interface"></a>
4672
<a name="n74"></a><H3>17.11.2 Functional interface without proxy classes</H3>
4675
It is possible to run SWIG in a mode that does not produce proxy classes by using the -noproxy commandline option.
4676
The interface is rather primitive when wrapping structures or classes and is accessed through function calls to the module class.
4677
All the functions in the module class are wrapped by functions with identical names as those in the intermediary JNI class.
4680
Consider the example we looked at when examining proxy classes:
4686
int spam(int num, Foo* foo);
4691
When using <tt>-noproxy</tt>, type wrapper classes are generated instead of proxy classes.
4692
Access to all the functions and variables is through a C like set of functions where the first parameter passed is the pointer to the class, that is an instance of a type wrapper class.
4693
Here is what the module class looks like:
4697
public class example {
4698
public static void set_Foo_x(SWIGTYPE_p_Foo self, int x) {...}
4699
public static int get_Foo_x(SWIGTYPE_p_Foo self) {...}
4700
public static int Foo_spam(SWIGTYPE_p_Foo self, int num, SWIGTYPE_p_Foo foo) {...}
4701
public static SWIGTYPE_p_Foo new_Foo() {...}
4702
public static void delete_Foo(SWIGTYPE_p_Foo self) {...}
4707
This approach is not nearly as natural as using proxy classes as the functions need to be used like this:
4711
SWIGTYPE_p_Foo foo = example.new_Foo();
4712
example.set_Foo_x(foo, 10);
4713
int var = example.get_Foo_x(foo);
4714
example.Foo_spam(foo, 20, foo);
4715
example.delete_Foo(foo);
4719
Unlike proxy classes, there is no attempt at tracking memory.
4720
All destructors have to be called manually for example the <tt>delete_Foo(foo)</tt> call above.
4723
<a name="using_own_jni_functions"></a>
4724
<a name="n75"></a><H3>17.11.3 Using your own JNI functions</H3>
4727
You may have some hand written JNI functions that you want to use in addition to the SWIG generated JNI functions.
4728
Adding these to your SWIG generated package is possible using the <tt>%native</tt> directive.
4729
If you don't want SWIG to wrap your JNI function then of course you can simply use the <tt>%ignore</tt> directive.
4730
However, if you want SWIG to generate just the Java code for a JNI function then use the <tt>%native</tt> directive.
4731
The C types for the parameters and return type must be specified in place of the JNI types and the function name must be the native method name.
4735
%native (HandRolled) void HandRolled(int, char *);
1919
#include "MyClass.h"
4737
JNIEXPORT void JNICALL Java_packageName_moduleName_HandRolled(JNIEnv *, jclass, jlong, jstring);
1921
%include "MyClass.h"
1923
// Use a shadow pragma without modifying the original code in MyClass.h
1924
%addmethods MyClass{
1925
%pragma(java) shadowcode="/* Some extra shadow code for MyClass */"
1930
<a name="n10"></a><h2>Dynamic linking problems</h2>
1931
The code to load a native library is <code>System.loadLibrary("name")</code>. This can fail and it can be due to a number of reasons.
1933
The most common is an incorrect naming of the native library for the name passed to the <code>loadLibrary</code> function. The text passed to the <code>loadLibrary</code> function must not include the the extension name in the text, that is <i>.dll</i> or <i>.so</i>. The text must be <i>name</i> and not <i>libname</i> for all platforms. On Windows the native library must then be called <i>name.dll</i> and on Unix it must be called <i>libname.so</i>. If you are debugging using <code> java -debug</code>, then the native library must be called <i>name_g.dll</i> on Windows and <i>libname_g.so</i> on Unix.
1935
Another common reason for the native library not loading is because it is not in your path. On Unix make sure that your <i>LD_LIBRARY_PATH</i> contains the path to the native library. On Windows make sure the <i>path</i> environment variable contains the path to the native library. SWIG code usually works if you have <i>LD_LIBRARY_PATH</i> set to '.' (or no modification to <i>path</i> in Windows).
1937
The native library will also not load if there are any unresolved symbols in the compiled C/C++ code. Unresolved symbols will be described if you use the -verbose:jni commandline switch when running java.
1939
Ensure that you are using the correct C/C++ compiler and linker combination and options for successful native library loading. The Examples/Makefile must have these set up correctly for your system. The SWIG installation package makes a best attempt at getting these correct but does not get it right 100% of the time.
1941
Linking problems used to occur when there were underscores in the module name or package name. This was fixed in SWIG 1.3.7.
1943
<a name="n11"></a><h2>Tips</h2>
1946
The %native directive can be used to mix hand written JNI functions with the auto generated functions.
1949
<a name="n12"></a><h2>Known bugs</h2>
1951
<li>Function pointers produce code that won't compile. Your own typemaps will overcome this.</li>
4741
No C JNI function will be generated and the <tt>Java_packageName_moduleName_HandRolled</tt> function will be accessible using the SWIG generated Java native method call in the intermediary JNI class which will look like this:
4744
public final static native void HandRolled(int jarg1, String jarg2);
4747
and as usual this function is wrapped by another which for a global C function would appear in the module class:
4750
public static void HandRolled(int arg0, String arg1) {
4751
exampleJNI.HandRolled(arg0, arg1);
4755
The <tt>packageName</tt> and <tt>moduleName</tt> must of course be correct else you will get linker errors when the JVM dynamically loads the JNI function.
4756
You may have to add in some "jtype", "jstype", "javain" and "javaout" typemaps when wrapping some JNI types.
4757
Here the default typemaps work for for <tt>int</tt> and <tt>char *</tt>.
4760
In summary the <tt>%native</tt> directive is telling SWIG to generate the Java code to access the JNI C code, but not the JNI C function itself.
4761
This directive is only really useful if you want to mix your own hand crafted JNI code and the SWIG generated code into one Java class or package.
4764
<a name="performance"></a>
4765
<a name="n76"></a><H3>17.11.4 Performance concerns and hints</H3>
4768
If you're directly manipulating huge arrays of complex objects from Java, performance may suffer greatly when using the array functions in <tt>arrays_java.i</tt>.
4769
Try and minimise the expensive JNI calls to C/C++ functions, perhaps by using temporary Java variables instead of accessing the information directly from the C/C++ object.<p>
4771
Java classes without any finalizers generally speed up code execution as there is less for the garbage collector to do. Finalizer generation can be stopped by using an empty <tt>javafinalize</tt> typemap:
4774
%typemap(javafinalize) SWIGTYPE ""
4777
However, you will have to be careful about memory management and make sure that you code in a call to the <tt>delete()</tt> member function.
4778
This method calls the C++ destructor or <tt>free()</tt> for C code.
4782
<a name="java_examples"></a>
4783
<a name="n77"></a><H2>17.12 Examples</H2>
4786
The directory Examples/java has a number of further examples.
4787
Take a look at these if you want to see some of the techniques described in action.
4788
The Examples/index.html file in the parent directory contains the SWIG Examples Documentation and is a useful starting point.
4789
If your SWIG installation went well Unix users should be able to type <tt>make</tt> in each example directory, then <tt>java main</tt> to see them running.
4790
For the benefit of Windows users, there are also Visual C++ project files in a couple of the <a href="Windows.html#examples">Windows Examples</a>.
b'\\ No newline at end of file'