blob: b9234b24f394a58a394ccf0c827f95aec4cb2f35 [file] [log] [blame]
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>SWIG and Java</title>
<link rel="stylesheet" type="text/css" href="style.css">
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
</head>
<body bgcolor="#FFFFFF">
<H1><a name="Java">27 SWIG and Java</a></H1>
<!-- INDEX -->
<div class="sectiontoc">
<ul>
<li><a href="#Java_overview">Overview</a>
<li><a href="#Java_preliminaries">Preliminaries</a>
<ul>
<li><a href="#Java_running_swig">Running SWIG</a>
<li><a href="#Java_commandline">Additional Commandline Options</a>
<li><a href="#Java_getting_right_headers">Getting the right header files</a>
<li><a href="#Java_compiling_dynamic">Compiling a dynamic module</a>
<li><a href="#Java_using_module">Using your module</a>
<li><a href="#Java_dynamic_linking_problems">Dynamic linking problems</a>
<li><a href="#Java_compilation_problems_cpp">Compilation problems and compiling with C++</a>
<li><a href="#Java_building_windows">Building on Windows</a>
<ul>
<li><a href="#Java_visual_studio">Running SWIG from Visual Studio</a>
<li><a href="#Java_nmake">Using NMAKE</a>
</ul>
</ul>
<li><a href="#Java_basic_tour">A tour of basic C/C++ wrapping</a>
<ul>
<li><a href="#Java_module_packages_classes">Modules, packages and generated Java classes</a>
<li><a href="#Java_functions">Functions</a>
<li><a href="#Java_global_variables">Global variables</a>
<li><a href="#Java_constants">Constants</a>
<li><a href="#Java_enumerations">Enumerations</a>
<ul>
<li><a href="#Java_anonymous_enums">Anonymous enums</a>
<li><a href="#Java_typesafe_enums">Typesafe enums</a>
<li><a href="#Java_proper_enums">Proper Java enums</a>
<li><a href="#Java_typeunsafe_enums">Type unsafe enums</a>
<li><a href="#Java_simple_enums">Simple enums</a>
</ul>
<li><a href="#Java_pointers">Pointers</a>
<li><a href="#Java_structures">Structures</a>
<li><a href="#Java_classes">C++ classes</a>
<li><a href="#Java_inheritance">C++ inheritance</a>
<li><a href="#Java_pointers_refs_arrays">Pointers, references, arrays and pass by value</a>
<ul>
<li><a href="#Java_null_pointers">Null pointers</a>
</ul>
<li><a href="#Java_overloaded_functions">C++ overloaded functions</a>
<li><a href="#Java_default_arguments">C++ default arguments</a>
<li><a href="#Java_namespaces">C++ namespaces</a>
<li><a href="#Java_templates">C++ templates</a>
<li><a href="#Java_smart_pointers">C++ Smart Pointers</a>
<ul>
<li><a href="#Java_smart_pointers_shared_ptr">The shared_ptr Smart Pointer</a>
<li><a href="#Java_smart_pointers_generic">Generic Smart Pointers</a>
</ul>
</ul>
<li><a href="#Java_further_details">Further details on the generated Java classes</a>
<ul>
<li><a href="#Java_imclass">The intermediary JNI class</a>
<ul>
<li><a href="#Java_imclass_pragmas">The intermediary JNI class pragmas</a>
</ul>
<li><a href="#Java_module_class">The Java module class</a>
<ul>
<li><a href="#Java_module_class_pragmas">The Java module class pragmas</a>
</ul>
<li><a href="#Java_proxy_classes">Java proxy classes</a>
<ul>
<li><a href="#Java_memory_management">Memory management</a>
<li><a href="#Java_inheritance_mirroring">Inheritance</a>
<li><a href="#Java_proxy_classes_gc">Proxy classes and garbage collection</a>
<li><a href="#Java_pgcpp">The premature garbage collection prevention parameter for proxy class marshalling</a>
<li><a href="#Java_multithread_libraries">Single threaded applications and thread safety</a>
</ul>
<li><a href="#Java_type_wrapper_classes">Type wrapper classes</a>
<li><a href="#Java_enum_classes">Enum classes</a>
<ul>
<li><a href="#Java_typesafe_enums_classes">Typesafe enum classes</a>
<li><a href="#Java_proper_enums_classes">Proper Java enum classes</a>
<li><a href="#Java_typeunsafe_enums_classes">Type unsafe enum classes</a>
</ul>
<li><a href="#Java_interfaces">Interfaces</a>
</ul>
<li><a href="#Java_directors">Cross language polymorphism using directors</a>
<ul>
<li><a href="#Java_enabling_directors">Enabling directors</a>
<li><a href="#Java_directors_classes">Director classes</a>
<li><a href="#Java_directors_overhead">Overhead and code bloat</a>
<li><a href="#Java_directors_example">Simple directors example</a>
<li><a href="#Java_directors_threading">Director threading issues</a>
<li><a href="#Java_directors_performance">Director performance tuning</a>
<li><a href="#Java_exceptions_from_directors">Java exceptions from directors</a>
<ul>
<li><a href="#Java_customizing_director_exceptions">Customizing director exceptions</a>
</ul>
</ul>
<li><a href="#Java_allprotected">Accessing protected members</a>
<li><a href="#Java_common_customization">Common customization features</a>
<ul>
<li><a href="#Java_helper_functions">C/C++ helper functions</a>
<li><a href="#Java_class_extension">Class extension with %extend</a>
<li><a href="#Java_proxycode">Class extension with %proxycode</a>
<li><a href="#Java_exception_handling">Exception handling with %exception and %javaexception</a>
<li><a href="#Java_method_access">Method access with %javamethodmodifiers</a>
</ul>
<li><a href="#Java_tips_techniques">Tips and techniques</a>
<ul>
<li><a href="#Java_input_output_parameters">Input and output parameters using primitive pointers and references</a>
<li><a href="#Java_simple_pointers">Simple pointers</a>
<li><a href="#Java_c_arrays">Wrapping C arrays with Java arrays</a>
<li><a href="#Java_unbounded_c_arrays">Unbounded C Arrays</a>
<li><a href="#Java_binary_char">Binary data vs Strings</a>
<li><a href="#Java_heap_allocations">Overriding new and delete to allocate from Java heap</a>
</ul>
<li><a href="#Java_typemaps">Java typemaps</a>
<ul>
<li><a href="#Java_default_primitive_type_mappings">Default primitive type mappings</a>
<li><a href="#Java_default_non_primitive_typemaps">Default typemaps for non-primitive types</a>
<li><a href="#Java_jvm64">Sixty four bit JVMs</a>
<li><a href="#Java_what_is_typemap">What is a typemap?</a>
<li><a href="#Java_typemaps_c_to_java_types">Typemaps for mapping C/C++ types to Java types</a>
<li><a href="#Java_typemap_attributes">Java typemap attributes</a>
<li><a href="#Java_special_variables">Java special variables</a>
<li><a href="#Java_typemaps_for_c_and_cpp">Typemaps for both C and C++ compilation</a>
<li><a href="#Java_code_typemaps">Java code typemaps</a>
<li><a href="#Java_directors_typemaps">Director specific typemaps</a>
</ul>
<li><a href="#Java_typemap_examples">Typemap Examples</a>
<ul>
<li><a href="#Java_simpler_enum_classes">Simpler Java enums for enums without initializers</a>
<li><a href="#Java_exception_typemap">Handling C++ exception specifications as Java exceptions</a>
<li><a href="#Java_nan_exception_typemap">NaN Exception - exception handling for a particular type</a>
<li><a href="#Java_converting_java_string_arrays">Converting Java String arrays to char ** </a>
<li><a href="#Java_expanding_java_object">Expanding a Java object to multiple arguments</a>
<li><a href="#Java_using_typemaps_return_arguments">Using typemaps to return arguments</a>
<li><a href="#Java_adding_downcasts">Adding Java downcasts to polymorphic return types</a>
<li><a href="#Java_adding_equals_method">Adding an equals method to the Java classes</a>
<li><a href="#Java_void_pointers">Void pointers and a common Java base class</a>
<li><a href="#Java_struct_pointer_pointer">Struct pointer to pointer</a>
<li><a href="#Java_memory_management_member_variables">Memory management when returning references to member variables</a>
<li><a href="#Java_memory_management_objects">Memory management for objects passed to the C++ layer</a>
<li><a href="#Java_date_marshalling">Date marshalling using the javain typemap and associated attributes</a>
</ul>
<li><a href="#Java_directors_faq">Living with Java Directors</a>
<li><a href="#Java_odds_ends">Odds and ends</a>
<ul>
<li><a href="#Java_javadoc_comments">JavaDoc comments</a>
<li><a href="#Java_functional_interface">Functional interface without proxy classes</a>
<li><a href="#Java_using_own_jni_functions">Using your own JNI functions</a>
<li><a href="#Java_performance">Performance concerns and hints</a>
<li><a href="#Java_debugging">Debugging</a>
</ul>
<li><a href="#Java_examples">Java Examples</a>
</ul>
</div>
<!-- INDEX -->
<p>
This chapter describes SWIG's support of Java.
It covers most SWIG features, but certain low-level details are covered in less depth than in earlier chapters.
</p>
<H2><a name="Java_overview">27.1 Overview</a></H2>
<p>
The 100% Pure Java effort is a commendable concept, however in the real world programmers often either need to re-use their existing code or in some situations
want to take advantage of Java but are forced into using some native (C/C++) code.
The Java extension to SWIG makes it very easy to plumb in existing C/C++ code for access from Java, as SWIG writes the Java Native Interface (JNI) code for you.
It is different to using the 'javah' tool as SWIG will wrap existing C/C++ code, whereas javah takes 'native' Java function declarations and creates C/C++ function prototypes.
SWIG wraps C/C++ code using Java proxy classes and is very useful if you want to have access to large amounts of C/C++ code from Java.
If only one or two JNI functions are needed then using SWIG may be overkill.
SWIG enables a Java program to easily call into C/C++ code from Java.
Historically, SWIG was not able to generate any code to call into Java code from C++.
However, SWIG now supports full cross language polymorphism and code is generated to call up from C++ to Java when wrapping C++ virtual methods via the director feature.
</p>
<p>
Java is one of the few non-scripting language modules in SWIG.
As SWIG utilizes the type safety that the Java language offers, it takes a somewhat different approach to that used for scripting languages.
In particular runtime type checking and the runtime library are not used by Java.
This should be borne in mind when reading the rest of the SWIG documentation.
This chapter on Java is relatively self contained and will provide you with nearly everything you need for using SWIG and Java.
However, the "<a href="SWIG.html#SWIG">SWIG Basics</a>" chapter will be a useful read in conjunction with this one.
</p>
<p>
This chapter starts with a few practicalities on running SWIG and compiling the generated code.
If you are looking for the minimum amount to read, have a look at the sections up to and including the
<a href="#Java_basic_tour">tour of basic C/C++ wrapping</a> section which explains how to call the various C/C++ code constructs from Java.
Following this section are details of the C/C++ code and Java classes that SWIG generates.
Due to the complexities of C and C++ there are different ways in which C/C++ code could be wrapped and called from Java.
SWIG is a powerful tool and the rest of the chapter details how the default code wrapping can be tailored.
Various customisation tips and techniques using SWIG directives are covered.
The latter sections cover the advanced techniques of using typemaps for complete control of the wrapping process.
</p>
<H2><a name="Java_preliminaries">27.2 Preliminaries</a></H2>
<p>
SWIG 1.1 works with JDKs from JDK 1.1 to JDK1.4 (Java 2 SDK1.4) and should also work with any later versions.
Given the choice, you should probably use the latest version of Sun's JDK.
The SWIG Java module is known to work using Sun's JVM on Solaris, Linux and the various flavours of Microsoft Windows including Cygwin.
The Kaffe JVM is known to give a few problems and at the time of writing was not a fully fledged JVM with full JNI support.
The generated code is also known to work on vxWorks using WindRiver's PJava 3.1.
The best way to determine whether your combination of operating system and JDK will work is to test the examples and test-suite that comes with SWIG.
Run <tt>make -k check</tt> from the SWIG root directory after installing SWIG on Unix systems. </p>
<p>
The Java module requires your system to support shared libraries and dynamic loading.
This is the commonly used method to load JNI code so your system will more than likely support this.</p>
<p>
Android uses Java JNI and also works with SWIG. Please read the <a href="Android.html#Android">Android chapter</a> in conjunction with this one if you are targeting Android.
</p>
<H3><a name="Java_running_swig">27.2.1 Running SWIG</a></H3>
<p>
Suppose that you defined a SWIG module such as the following:
</p>
<div class="code">
<pre>
/* File: example.i */
%module test
%{
#include "stuff.h"
%}
int fact(int n);
</pre>
</div>
<p>
To build a Java module, run SWIG using the <tt>-java</tt> option :</p>
<div class="code"><pre>
%swig -java example.i
</pre></div>
<p>
If building C++, add the <tt>-c++</tt> option:
</p>
<div class="code"><pre>
$ swig -c++ -java example.i
</pre></div>
<p>
This creates two different files; a C/C++ source file <tt>example_wrap.c</tt> or
<tt>example_wrap.cxx</tt> and numerous Java files. The generated
C/C++ source file contains the JNI wrapper code that needs to be compiled and linked with the
rest of your C/C++ application.
</p>
<p>
The name of the wrapper file is derived from the name of the input file. For example, if the
input file is <tt>example.i</tt>, the name of the wrapper file is <tt>example_wrap.c</tt>.
To change this, you can use the <tt>-o</tt> option.
It is also possible to change the <a href="SWIG.html#SWIG_output">output directory </a> that the Java files are generated into using <tt>-outdir</tt>.
</p>
<p>
The module name, specified with <tt>%module</tt>, determines the name of various generated classes as discussed <a href="#Java_module_packages_classes">later</a>.
Note that the module name does not define a Java package and by default, the generated Java classes do not have a Java package.
The <tt>-package</tt> option described below can specify a Java package name to use.
</p>
<p>
The following sections have further practical examples and details on how you might go about
compiling and using the generated files.
</p>
<H3><a name="Java_commandline">27.2.2 Additional Commandline Options</a></H3>
<p>
The following table lists the additional commandline options available for the Java module. They can also be seen by using:
</p>
<div class="code"><pre>
swig -java -help
</pre></div>
<table summary="Java specific options">
<tr>
<th>Java specific options</th>
</tr>
<tr>
<td>-nopgcpp</td>
<td>suppress the premature garbage collection prevention parameter</td>
</tr>
<tr>
<td>-noproxy</td>
<td>generate the low-level functional interface instead of proxy classes </td>
</tr>
<tr>
<td>-package &lt;name&gt;</td>
<td>set name of the Java package to &lt;name&gt;</td>
</tr>
</table>
<p>
Their use will become clearer by the time you have finished reading this section on SWIG and Java.
</p>
<H3><a name="Java_getting_right_headers">27.2.3 Getting the right header files</a></H3>
<p>
In order to compile the C/C++ wrappers, the compiler needs the <tt>jni.h</tt> and <tt>jni_md.h</tt> header files which are part of the JDK.
They are usually in directories like this:</p>
<div class="code"><pre>
/usr/java/include
/usr/java/include/&lt;operating_system&gt;
</pre></div>
<p>
The exact location may vary on your machine, but the above locations are typical. </p>
<H3><a name="Java_compiling_dynamic">27.2.4 Compiling a dynamic module</a></H3>
<p>
The JNI code exists in a dynamic module or shared library (DLL on Windows) and gets loaded by the JVM.
Assuming you have code you need to link to in a file called <tt>example.c</tt>, in order to build a shared library file, you need to compile your module in a manner similar to the following (shown for Solaris):</p>
<div class="code"><pre>
$ swig -java example.i
$ gcc -fPIC -c example_wrap.c -I/usr/java/include -I/usr/java/include/solaris
$ gcc -fPIC -c example.c
$ ld -G example_wrap.o example.o -o libexample.so
</pre></div>
<p>
The exact commands for doing this vary from platform to platform.
However, SWIG tries to guess the right options when it is installed. Therefore,
you may want to start with one of the examples in the <tt>Examples/java</tt>
directory. If that doesn't work, you will need to read the man-pages for
your compiler and linker to get the right set of options. You might also
check the <a href="https://github.com/swig/swig/wiki">SWIG Wiki</a> for
additional information.
</p>
<p>
<b>Important</b> <br>
If you are going to use optimisations turned on with gcc (for example -O2), ensure you also compile with -fno-strict-aliasing. The GCC optimisations have become
more aggressive from gcc-4.0 onwards and will result in code that fails with strict aliasing optimisations turned on. See the <a href="#Java_typemaps_c_to_java_types">C/C++ to Java typemaps</a> section for more details.
</p>
<p>
The name of the shared library output file is important.
If the name of your SWIG module is "<tt>example</tt>", the name of the corresponding shared library file should be "<tt>libexample.so</tt>" (or equivalent depending on your machine, see <a href="#Java_dynamic_linking_problems">Dynamic linking problems</a> for more information).
The name of the module is specified using the <tt>%module</tt> directive or <tt>-module</tt> command line option.</p>
<H3><a name="Java_using_module">27.2.5 Using your module</a></H3>
<p>
To load your shared native library module in Java, simply use Java's <tt>System.loadLibrary</tt> method in a Java class:</p>
<div class="code"><pre>
// runme.java
public class runme {
static {
System.loadLibrary("example");
}
public static void main(String argv[]) {
System.out.println(example.fact(4));
}
}
</pre></div>
<p>
Compile all the Java files and run:
</p>
<div class="code"><pre>
$ javac *.java
$ java runme
24
$
</pre></div>
<p>
If it doesn't work have a look at the following section which discusses problems loading the shared library.
</p>
<H3><a name="Java_dynamic_linking_problems">27.2.6 Dynamic linking problems</a></H3>
<p>
As shown in the previous section the code to load a native library (shared library) is <tt>System.loadLibrary("name")</tt>.
This can fail with an UnsatisfiedLinkError exception and can be due to a number of reasons.
</p>
<p>
You may get an exception similar to this:
</p>
<div class="code"><pre>
$ java runme
Exception in thread "main" java.lang.UnsatisfiedLinkError: no example in java.library.path
at java.lang.ClassLoader.loadLibrary(ClassLoader.java:1312)
at java.lang.Runtime.loadLibrary0(Runtime.java:749)
at java.lang.System.loadLibrary(System.java:820)
at runme.&lt;clinit&gt;(runme.java:5)
</pre></div>
<p>
The most common cause for this is an incorrect naming of the native library for the name passed to the <tt>loadLibrary</tt> function.
The string passed to the <tt>loadLibrary</tt> function must not include the file extension name in the string, that is <i>.dll</i> or <i>.so</i>.
The string 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 most Unix systems it must be called <i>libname.so</i>.
</p>
<p>
Another common reason for the native library not loading is because it is not in your path.
On Windows make sure the <i>path</i> environment variable contains the path to the native library.
On Unix make sure that your <i>LD_LIBRARY_PATH</i> contains the path to the native library.
Adding paths to <i>LD_LIBRARY_PATH</i> can slow down other programs on your system so you may want to consider alternative approaches.
For example you could recompile your native library with extra path information using <tt>-rpath</tt> if you're using GNU, see the GNU linker documentation (<tt>ld</tt> man page).
You could use a command such as <tt>ldconfig</tt> (Linux) or
<tt>crle</tt> (Solaris) to add additional search paths to the default
system configuration (this requires root access and you will need to read the man pages).
</p>
<p>
The native library will also not load if there are any unresolved symbols in the compiled C/C++ code.
The following exception is indicative of this:
</p>
<div class="code"><pre>
$ java runme
Exception in thread "main" java.lang.UnsatisfiedLinkError: libexample.so: undefined
symbol: fact
at java.lang.ClassLoader$NativeLibrary.load(Native Method)
at java.lang.ClassLoader.loadLibrary0(ClassLoader.java, Compiled Code)
at java.lang.ClassLoader.loadLibrary(ClassLoader.java, Compiled Code)
at java.lang.Runtime.loadLibrary0(Runtime.java, Compiled Code)
at java.lang.System.loadLibrary(System.java, Compiled Code)
at runme.&lt;clinit&gt;(runme.java:5)
$
</pre></div>
<p>
This error usually indicates that you forgot to include some object files or libraries in the linking of the native library file.
Make sure you compile both the SWIG wrapper file and the code you are wrapping into the native library file.
If you forget to compile and link in the SWIG wrapper file into your native library file, you will get a message similar to the following:
</p>
<div class="code"><pre>
$ java runme
Exception in thread "main" java.lang.UnsatisfiedLinkError: exampleJNI.gcd(II)I
at exampleJNI.gcd(Native Method)
at example.gcd(example.java:12)
at runme.main(runme.java:18)
</pre></div>
<p>
where <tt>gcd</tt> is the missing JNI function that SWIG generated into the wrapper file.
Also make sure you pass all of the required libraries to the linker.
The <tt>java -verbose:jni</tt> commandline option is also a great way to get more information on unresolved symbols.
One last piece of advice is to beware of the common faux pas of having more than one native library version in your path.
</p>
<p>
In summary, ensure that you are using the correct C/C++ compiler and linker combination and options for successful native library loading.
If you are using the examples that ship with SWIG, then 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.
The <a href="https://github.com/swig/swig/wiki">SWIG Wiki</a> also has some settings for commonly used compiler and operating system combinations.
The following section also contains some C++ specific linking problems and solutions.
</p>
<H3><a name="Java_compilation_problems_cpp">27.2.7 Compilation problems and compiling with C++</a></H3>
<p>
On most machines, shared library files should be linked using the C++
compiler. For example:
</p>
<div class="code"><pre>
% swig -c++ -java example.i
% g++ -c -fpic example.cxx
% g++ -c -fpic example_wrap.cxx -I/usr/java/j2sdk1.4.1/include -I/usr/java/j2sdk1.4.1/include/linux
% g++ -shared example.o example_wrap.o -o libexample.so
</pre></div>
<p>
In addition to this, you may need to include additional library
files to make it work. For example, if you are using the Sun C++ compiler on
Solaris, you often need to add an extra library <tt>-lCrun</tt> like this:
</p>
<div class="code"><pre>
% swig -c++ -java example.i
% CC -c example.cxx
% CC -c example_wrap.cxx -I/usr/java/include -I/usr/java/include/solaris
% CC -G example.o example_wrap.o -L/opt/SUNWspro/lib -o libexample.so -lCrun
</pre></div>
<p>
If you aren't entirely sure about the linking for C++, you
might look at an existing C++ program. On many Unix machines, the
<tt>ldd</tt> command will list library dependencies. This should give
you some clues about what you might have to include when you link your
shared library. For example:
</p>
<div class="code">
<pre>
$ ldd swig
libstdc++-libc6.1-1.so.2 =&gt; /usr/lib/libstdc++-libc6.1-1.so.2 (0x40019000)
libm.so.6 =&gt; /lib/libm.so.6 (0x4005b000)
libc.so.6 =&gt; /lib/libc.so.6 (0x40077000)
/lib/ld-linux.so.2 =&gt; /lib/ld-linux.so.2 (0x40000000)
$
</pre>
</div>
<p>
Finally make sure the version of JDK header files matches the version of Java that you are running as incompatibilities could lead to compilation problems or unpredictable behaviour.
</p>
<H3><a name="Java_building_windows">27.2.8 Building on Windows</a></H3>
<p>
Building on Windows is roughly similar to the process used with Unix.
You will want to produce a DLL that can be loaded by the Java Virtual Machine.
This section covers the process of using SWIG with Microsoft Visual C++ 6 although the procedure may be similar with other compilers.
In order for everything to work, you will need to have a JDK installed on your machine in order to read the JNI header files.</p>
<H4><a name="Java_visual_studio">27.2.8.1 Running SWIG from Visual Studio</a></H4>
<p>
If you are developing your application within Microsoft Visual studio, SWIG can be invoked as a custom build option.
The Examples\java directory has a few <a href="Windows.html#Windows_examples">Windows Examples</a> containing Visual Studio project (.dsp) files.
The process to re-create the project files for a C project are roughly:</p>
<ul>
<li>Open up a new workspace and use the AppWizard to select a DLL project.
<li>Add both the SWIG interface file (the .i file), any supporting C files, and the name of the wrapper file that will be created by SWIG (ie. <tt>example_wrap.c</tt>).
Don't worry if the wrapper file doesn't exist yet--Visual Studio will keep a reference to it.
<li>Select the SWIG interface file and go to the settings menu. Under settings, select the "Custom Build" option.
<li>Enter "SWIG" in the description field.
<li>Enter "<tt>swig -java -o $(ProjDir)\$(InputName)_wrap.c $(InputPath)</tt>" in the "Build command(s) field"
<li>Enter "<tt>$(ProjDir)\$(InputName)_wrap.c</tt>" in the "Output files(s) field".
<li>Next, select the settings for the entire project and go to C/C++ tab and select the Preprocessor category. Add the include directories to the JNI header files under "Additional include directories", eg "C:\jdk1.3\include, C:\jdk1.3\include\win32".
<li>Next, select the settings for the entire project and go to Link tab and select the General category. Set the name of the output file to match the name of your Java module (ie. example.dll).
<li>Next, select the example.c and example_wrap.c files and go to the C/C++ tab and select the Precompiled Headers tab in the project settings. Disabling precompiled headers for these files will overcome any precompiled header errors while building.
<li>Finally, add the java compilation as a post build rule in the Post-build step tab in project settings, eg, "c:\jdk1.3\bin\javac *.java"
<li>Build your project.
</ul>
<p>
Note: If using C++, choose a C++ suffix for the wrapper file, for example <tt>example_wrap.cxx</tt>.
Use <tt>_wrap.cxx</tt> instead of <tt>_wrap.c</tt> in the instructions above and add -c++ when invoking swig.
</p>
<p>
Now, assuming all went well, SWIG will be automatically invoked when you build your project.
When doing a build, any changes made to the interface file will result in SWIG being automatically invoked to produce a new version of the wrapper file.
</p>
<p>
The Java classes that SWIG output should also be compiled into .class files.
To run the native code in the DLL (example.dll), make sure that it is in your path then run your Java program which uses it, as described in the previous section.
If the library fails to load have a look at <a href="#Java_dynamic_linking_problems">Dynamic linking problems</a>.
</p>
<H4><a name="Java_nmake">27.2.8.2 Using NMAKE</a></H4>
<p>
Alternatively, a Makefile for use by NMAKE can be written.
Make sure the environment variables for MSVC++ are available and the MSVC++ tools are in your path.
Now, just write a short Makefile like this :</p>
<div class="code"><pre>
# Makefile for using SWIG and Java for C code
SRCS = example.c
IFILE = example
INTERFACE = $(IFILE).i
WRAPFILE = $(IFILE)_wrap.c
# Location of the Visual C++ tools (32 bit assumed)
TOOLS = c:\msdev
TARGET = example.dll
CC = $(TOOLS)\bin\cl.exe
LINK = $(TOOLS)\bin\link.exe
INCLUDE32 = -I$(TOOLS)\include
MACHINE = IX86
# C Library needed to build a DLL
DLLIBC = msvcrt.lib oldnames.lib
# Windows libraries that are apparently needed
WINLIB = kernel32.lib advapi32.lib user32.lib gdi32.lib comdlg32.lib winspool.lib
# Libraries common to all DLLs
LIBS = $(DLLIBC) $(WINLIB)
# Linker options
LOPT = -debug:full -debugtype:cv /NODEFAULTLIB /RELEASE /NOLOGO \
/MACHINE:$(MACHINE) -entry:_DllMainCRTStartup@12 -dll
# C compiler flags
CFLAGS = /Z7 /Od /c /nologo
JAVA_INCLUDE = -ID:\jdk1.3\include -ID:\jdk1.3\include\win32
java::
swig -java -o $(WRAPFILE) $(INTERFACE)
$(CC) $(CFLAGS) $(JAVA_INCLUDE) $(SRCS) $(WRAPFILE)
set LIB=$(TOOLS)\lib
$(LINK) $(LOPT) -out:example.dll $(LIBS) example.obj example_wrap.obj
javac *.java
</pre></div>
<p>
To build the DLL and compile the java code, 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.
Of course you may want to make changes for it to work for C++ by adding in the -c++ command line option for swig and replacing .c with .cxx.
</p>
<H2><a name="Java_basic_tour">27.3 A tour of basic C/C++ wrapping</a></H2>
<p>
By default, SWIG attempts to build a natural Java interface
to your C/C++ code. Functions are wrapped as functions, classes are wrapped as classes,
variables are wrapped with JavaBean type getters and setters and so forth.
This section briefly covers the essential aspects of this wrapping.
</p>
<H3><a name="Java_module_packages_classes">27.3.1 Modules, packages and generated Java classes</a></H3>
<p>
The SWIG <tt>%module</tt> directive specifies the name of the Java
module. When you specify `<tt>%module example</tt>', the <i>module name</i>
determines the name of some of the generated files in the module.
The generated code consists of a <i>module class</i> file <tt>example.java</tt>, an
<i>intermediary JNI class</i> file, <tt>exampleJNI.java</tt> as well as numerous other Java <i>proxy class</i> files.
Each proxy class is named after the structs, unions and classes you are wrapping.
You may also get a <i>constants interface</i> file if you are wrapping any unnamed enumerations or constants, for example <tt>exampleConstants.java</tt>.
When choosing a module name, make sure you don't use the same name as one of the generated
proxy class files nor a Java keyword. Sometimes a C/C++ type cannot be wrapped by a proxy class, for
example a pointer to a primitive type. In these situations a <i>type wrapper class</i> is generated.
Wrapping an enum generates an <i>enum class</i>, either a proper Java enum or a Java class that simulates the enums pattern.
Details of all these generated classes will unfold as you read this section.
</p>
<p>
The JNI (C/C++) code is generated into a file which also contains the module name, for example <tt>example_wrap.cxx</tt>
or <tt>example_wrap.c</tt>. These C or C++ files complete the contents of the module.
</p>
<p>
The generated Java classes can be placed into a Java package by using the <tt>-package</tt> commandline option.
This is often combined with the <tt>-outdir</tt> to specify a package directory for generating the Java files.
</p>
<div class="code"><pre>
swig -java -package com.bloggs.swig -outdir com/bloggs/swig example.i
</pre></div>
<p>
SWIG won't create the directory, so make sure it exists beforehand.
</p>
<H3><a name="Java_functions">27.3.2 Functions</a></H3>
<p>
There is no such thing as a global Java function so global C functions are wrapped as static methods in
the module class. For example,
</p>
<div class="code"><pre>
%module example
int fact(int n);
</pre></div>
<p>
creates a static function that works exactly like you think it might:</p>
<div class="code"><pre>
public class example {
public static int fact(int n) {
// makes call using JNI to the C function
}
}
</pre></div>
<p>
The Java class <tt>example</tt> is the <i>module class</i>. The function can be used as follows from Java:</p>
<div class="code"><pre>
System.out.println(example.fact(4));
</pre></div>
<H3><a name="Java_global_variables">27.3.3 Global variables</a></H3>
<p>
C/C++ global variables are fully supported by SWIG.
Java does not allow the overriding of the dot operator so all variables are accessed through getters and setters.
Again because there is no such thing as a
Java global variable, access to C/C++ global variables is done through static getter and setter functions in the module class.
</p>
<div class="code"><pre>
// SWIG interface file with global variables
%module example
...
%inline %{
extern int My_variable;
extern double density;
%}
...
</pre></div>
<p>
Now in Java :</p>
<div class="code"><pre>
// Print out value of a C global variable
System.out.println("My_variable = " + example.getMy_variable());
// Set the value of a C global variable
example.setDensity(0.8442);
</pre></div>
<p>
The value returned by the getter will always be up to date even if the value is changed in C.
Note that the getters and setters produced follow the JavaBean property design pattern.
That is the first letter of the variable name is capitalized and preceded with set or get.
If you have the misfortune of wrapping two variables that differ only in the capitalization of their first letters,
use %rename to change one of the variable names. For example:
</p>
<div class="code"><pre>
%rename Clash RenamedClash;
float Clash;
int clash;
</pre></div>
<p>
If a variable is declared as <tt>const</tt>, it is wrapped as a read-only variable.
That is only a getter is produced.
</p>
<p>
To make ordinary variables read-only, you can use the <tt>%immutable</tt> directive. For example:
</p>
<div class="code">
<pre>
%{
extern char *path;
%}
%immutable;
extern char *path;
%mutable;
</pre>
</div>
<p>
The <tt>%immutable</tt> directive stays in effect until it is explicitly disabled or cleared using
<tt>%mutable</tt>.
See the <a href="SWIG.html#SWIG_readonly_variables">Creating read-only variables</a> section for further details.
</p>
<p>
If you just want to make a specific variable immutable, supply a declaration name. For example:
</p>
<div class="code">
<pre>
%{
extern char *path;
%}
%immutable path;
...
extern char *path; // Read-only (due to %immutable)
</pre>
</div>
<H3><a name="Java_constants">27.3.4 Constants</a></H3>
<p>
C/C++ constants are wrapped as Java static final variables.
To create a constant, use <tt>#define</tt> or the
<tt>%constant</tt> directive. For example:
</p>
<div class="code">
<pre>
#define PI 3.14159
#define VERSION "1.0"
%constant int FOO = 42;
%constant const char *path = "/usr/local";
</pre>
</div>
<p>
By default the generated static final variables are initialized by making a JNI call to get their value.
The constants are generated into the constants interface and look like this:
</p>
<div class="code"><pre>
public interface exampleConstants {
public final static double PI = exampleJNI.PI_get();
public final static String VERSION = exampleJNI.VERSION_get();
public final static int FOO = exampleJNI.FOO_get();
public final static String path = exampleJNI.path_get();
}
</pre></div>
<p>
Note that SWIG has inferred the C type and used an appropriate Java type that will fit the range of all possible values for the C type.
By default SWIG generates <b>runtime constants</b>. They are not <b>compiler constants</b> that can, for example, be used
in a switch statement. This can be changed by using the <tt>%javaconst(flag)</tt> directive. It works like all
the other <a href="Customization.html#Customization_features">%feature directives</a>. The default is <tt>%javaconst(0)</tt>.
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.
Putting it at the top of your interface file would ensure this.
Here is an example:
</p>
<div class="code"><pre>
%javaconst(1);
%javaconst(0) BIG;
%javaconst(0) LARGE;
#define EXPRESSION (0x100+5)
#define BIG 1000LL
#define LARGE 2000ULL
</pre></div>
<p>
generates:
</p>
<div class="code"><pre>
public interface exampleConstants {
public final static int EXPRESSION = (0x100+5);
public final static long BIG = exampleJNI.BIG_get();
public final static java.math.BigInteger LARGE = exampleJNI.LARGE_get();
}
</pre></div>
<p>
Note that SWIG has inferred the C <tt>long long</tt> type from <tt>BIG</tt> and used an appropriate Java type (<tt>long</tt>) as
a Java <tt>long</tt> is the smallest sized Java type that will take all possible values for a C <tt>long long</tt>.
Similarly for <tt>LARGE</tt>.
</p>
<p>
Be careful using the <tt>%javaconst(1)</tt> directive as not all C code will compile as Java code. For example neither the
<tt>1000LL</tt> value for <tt>BIG</tt> nor <tt>2000ULL</tt> for <tt>LARGE</tt> above would generate valid Java code.
The example demonstrates how you can target particular constants (<tt>BIG</tt> and <tt>LARGE</tt>) with <tt>%javaconst</tt>.
SWIG doesn't use <tt>%javaconst(1)</tt> as the default as it tries to generate code that will always compile.
However, using a <tt>%javaconst(1)</tt> at the top of your interface file is strongly recommended as the preferred compile time constants
will be generated and most C constants will compile as Java code and in any case the odd constant that doesn't can be fixed using <tt>%javaconst(0)</tt>.
</p>
<p>
There is an alternative directive which can be used for these rare constant values that won't compile as Java code.
This is the <tt>%javaconstvalue(value)</tt> directive, where <tt>value</tt> is a Java code replacement for the C constant and can be either a string or a number.
This is useful if you do not want to use either the parsed C value nor a JNI call,
such as when the C parsed value will not compile as Java code and a compile time constant is required.
The same example demonstrates this:
</p>
<div class="code"><pre>
%javaconst(1);
%javaconstvalue("new java.math.BigInteger(\"2000\")") LARGE;
%javaconstvalue(1000) BIG;
#define EXPRESSION (0x100+5)
#define BIG 1000LL
#define LARGE 2000ULL
</pre></div>
<p>
Note the string quotes for <tt>"2000"</tt> are escaped. The following is then generated:
</p>
<div class="code"><pre>
public interface exampleConstants {
public final static int EXPRESSION = (0x100+5);
public final static long BIG = 1000;
public final static java.math.BigInteger LARGE = new java.math.BigInteger("2000");
}
</pre></div>
<p>
Note: declarations declared as <tt>const</tt> are wrapped as read-only variables and
will be accessed using a getter as described in the previous section. They
are not wrapped as constants.
The exception to this rule are static const integral values defined within a class/struct, where they are wrapped as constants, eg:.
</p>
<div class="code"><pre>
struct Maths {
static const int FIVE = 5;
};
</pre></div>
<p>
<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.
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):
</p>
<div class="code"><pre>
public class example implements exampleConstants {
}
</pre></div>
<p>
You thus have the choice of accessing these constants from either the module class or the constants interface, for example,
<tt>example.EXPRESSION</tt> or <tt>exampleConstants.EXPRESSION</tt>.
Or if you decide this practice isn't so bad and your own class implements <tt>exampleConstants</tt>, you can of course just use <tt>EXPRESSION</tt>.
</p>
<H3><a name="Java_enumerations">27.3.5 Enumerations</a></H3>
<p>
SWIG handles both named and unnamed (anonymous) enumerations.
There is a choice of approaches to wrapping named C/C++ enums.
This is due to historical reasons as SWIG's initial support for enums was limited and Java did not originally have support for enums.
Each approach has advantages and disadvantages and it is important for the user to decide which is the most appropriate solution.
There are four approaches of which the first is the default approach based on the so called Java typesafe enum pattern.
The second generates proper Java enums.
The final two approaches use simple integers for each enum item.
Before looking at the various approaches for wrapping named C/C++ enums, anonymous enums are considered.
</p>
<H4><a name="Java_anonymous_enums">27.3.5.1 Anonymous enums</a></H4>
<p>
There is no name for anonymous enums and so they are handled like constants. For example:
</p>
<div class="code">
<pre>
enum { ALE, LAGER=10, STOUT, PILSNER, PILZ=PILSNER };
</pre>
</div>
<p>
is wrapped into the constants interface, in a similar manner as constants (see previous section):
</p>
<div class="code"><pre>
public interface exampleConstants {
public final static int ALE = exampleJNI.ALE_get();
public final static int LAGER = exampleJNI.LAGER_get();
public final static int STOUT = exampleJNI.STOUT_get();
public final static int PILSNER = exampleJNI.PILSNER_get();
public final static int PILZ = exampleJNI.PILZ_get();
}
</pre></div>
<p>
The <tt>%javaconst(flag)</tt> and <tt>%javaconstvalue(value)</tt> directive introduced in the previous section on constants can also be used with enums.
As is the case for constants, the default is <tt>%javaconst(0)</tt> as not all C values will compile as Java code.
However, it is strongly recommended to add in a <tt>%javaconst(1)</tt> directive at the top of your
interface file as it is only on very rare occasions that this will produce code that won't compile under Java.
Using <tt>%javaconst(1)</tt> will ensure compile time constants are generated, thereby allowing the enum values to be used in Java switch statements.
Example usage:
</p>
<div class="code">
<pre>
%javaconst(1);
%javaconst(0) PILSNER;
enum { ALE, LAGER=10, STOUT, PILSNER, PILZ=PILSNER };
</pre>
</div>
<p>
generates:
</p>
<div class="code"><pre>
public interface exampleConstants {
public final static int ALE = 0;
public final static int LAGER = 10;
public final static int STOUT = LAGER + 1;
public final static int PILSNER = exampleJNI.PILSNER_get();
public final static int PILZ = PILSNER;
}
</pre></div>
<p>
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>.
</p>
<H4><a name="Java_typesafe_enums">27.3.5.2 Typesafe enums</a></H4>
<p>
This is the default approach to wrapping named enums.
The typesafe enum pattern is a relatively well known construct to work around the lack of enums in versions of Java prior to JDK 1.5.
It basically defines a class for the enumeration and permits a limited number of final static instances of the class.
Each instance equates to an enum item within the enumeration.
The implementation is in the "enumtypesafe.swg" file.
Let's look at an example:
</p>
<div class="code">
<pre>
%include "enumtypesafe.swg" // optional as typesafe enums are the default
enum Beverage { ALE, LAGER=10, STOUT, PILSNER, PILZ=PILSNER };
</pre>
</div>
<p>will generate:</p>
<div class="code">
<pre>
public final class Beverage {
public final static Beverage ALE = new Beverage("ALE");
public final static Beverage LAGER = new Beverage("LAGER", exampleJNI.LAGER_get());
public final static Beverage STOUT = new Beverage("STOUT");
public final static Beverage PILSNER = new Beverage("PILSNER");
public final static Beverage PILZ = new Beverage("PILZ", exampleJNI.PILZ_get());
[... additional support methods omitted for brevity ...]
}
</pre>
</div>
<p>
See <a href="#Java_typesafe_enums_classes">Typesafe enum classes</a> to see the omitted support methods.
Note that the enum item with an initializer (LAGER) is initialized with the enum value obtained via a JNI call.
However, as with anonymous enums and constants, use of the <tt>%javaconst</tt> directive is strongly recommended to change this behaviour:
</p>
<div class="code">
<pre>
%include "enumtypesafe.swg" // optional as typesafe enums are the default
%javaconst(1);
enum Beverage { ALE, LAGER=10, STOUT, PILSNER, PILZ=PILSNER };
</pre>
</div>
<p>
will generate:
</p>
<div class="code">
<pre>
public final class Beverage {
public final static Beverage ALE = new Beverage("ALE");
public final static Beverage LAGER = new Beverage("LAGER", 10);
public final static Beverage STOUT = new Beverage("STOUT");
public final static Beverage PILSNER = new Beverage("PILSNER");
public final static Beverage PILZ = new Beverage("PILZ", PILSNER);
[... additional support methods omitted for brevity ...]
}
</pre>
</div>
<p>
The generated code is easier to read and more efficient as a true constant is used instead of a JNI call.
As is the case for constants, the default is <tt>%javaconst(0)</tt> as not all C values will compile as Java code.
However, it is recommended to add in a <tt>%javaconst(1)</tt> directive at the top of your
interface file as it is only on very rare occasions that this will produce code that won't compile under Java.
The <tt>%javaconstvalue(value)</tt> directive can also be used for typesafe enums.
Note that global enums are generated into a Java class within whatever package you are using.
C++ enums defined within a C++ class are generated into a static final inner Java class within the Java proxy class.
</p>
<p>
Typesafe enums have their advantages over using plain integers in that they can be used in a typesafe manner.
However, there are limitations. For example, they cannot be used in switch statements and serialization is an issue.
Please look at the following references for further information:
<a href="http://java.sun.com/developer/Books/shiftintojava/page1.html#replaceenums">Replace Enums with Classes</a> in <i>Effective Java Programming</i> on the Sun website,
<a href="https://www.javaworld.com/article/2076970/create-enumerated-constants-in-java.html">Create enumerated constants in Java</a> JavaWorld article,
<a href="https://www.javaworld.com/article/2077499/java-tip-133--more-on-typesafe-enums.html">Java Tip 133: More on typesafe enums</a> and
<a href="https://www.javaworld.com/article/2077487/java-tip-122--beware-of-java-typesafe-enumerations.html">Java Tip 122: Beware of Java typesafe enumerations</a> JavaWorld tips.
</p>
<p>
Note that the syntax required for using typesafe enums is the same as that for proper Java enums.
This is useful during the period that a project has to support legacy versions of Java.
When upgrading to JDK 1.5 or later, proper Java enums could be used instead, without users having to change their code.
The following section details proper Java enum generation.
</p>
<H4><a name="Java_proper_enums">27.3.5.3 Proper Java enums</a></H4>
<p>
Proper Java enums were only introduced in JDK 1.5 so this approach is only compatible with more recent versions of Java.
Java enums have been designed to overcome all the limitations of both typesafe and type unsafe enums
and should be the choice solution, provided older versions of Java do not have to be supported.
In this approach, each named C/C++ enum is wrapped by a Java enum.
Java enums, by default, do not support enums with initializers.
Java enums are in many respects similar to Java classes in that they can be customised with additional methods.
SWIG takes advantage of this feature to facilitate wrapping C/C++ enums that have initializers.
In order to wrap all possible C/C++ enums using proper Java enums, the "enums.swg" file must be used.
Let's take a look at an example.
</p>
<div class="code">
<pre>
%include "enums.swg"
%javaconst(1);
enum Beverage { ALE, LAGER=10, STOUT, PILSNER, PILZ=PILSNER };
</pre>
</div>
<p>
will generate:
</p>
<div class="code">
<pre>
public enum Beverage {
ALE,
LAGER(10),
STOUT,
PILSNER,
PILZ(PILSNER);
[... additional support methods omitted for brevity ...]
}
</pre>
</div>
<p>
See <a href="#Java_proper_enums_classes">Proper Java enum classes</a> to see the omitted support methods.
The generated Java enum has numerous additional methods to support enums with initializers, such as <tt>LAGER</tt> above.
Note that as with the typesafe enum pattern, enum items with initializers are by default initialized with the enum value obtained via a JNI call.
However, this is not the case above as we have used the recommended <tt>%javaconst(1)</tt> to avoid the JNI call.
The <tt>%javaconstvalue(value)</tt> directive covered in the <a href="#Java_constants">Constants</a> section can also be used for proper Java enums.
</p>
<p>
The additional support methods need not be generated if none of the enum items have initializers and this is covered later in the
<a href="#Java_simpler_enum_classes">Simpler Java enums for enums without initializers</a> section.
</p>
<H4><a name="Java_typeunsafe_enums">27.3.5.4 Type unsafe enums</a></H4>
<p>
In this approach each enum item in a named enumeration is wrapped as a static final integer in a class named after the C/C++ enum name.
This is a commonly used pattern in Java to simulate C/C++ enums, but it is not typesafe.
However, the main advantage over the typesafe enum pattern is enum items can be used in switch statements.
In order to use this approach, the "enumtypeunsafe.swg" file must be used.
Let's take a look at an example.
</p>
<div class="code">
<pre>
%include "enumtypeunsafe.swg"
%javaconst(1);
enum Beverage { ALE, LAGER=10, STOUT, PILSNER, PILZ=PILSNER };
</pre>
</div>
<p>
will generate:
</p>
<div class="code">
<pre>
public final class Beverage {
public final static int ALE = 0;
public final static int LAGER = 10;
public final static int STOUT = LAGER + 1;
public final static int PILSNER = STOUT + 1;
public final static int PILZ = PILSNER;
}
</pre>
</div>
<p>
As is the case previously, the default is <tt>%javaconst(0)</tt> as not all C/C++ values will compile as Java code.
However, again it is recommended to add in a <tt>%javaconst(1)</tt> directive.
and the <tt>%javaconstvalue(value)</tt> directive covered in the <a href="#Java_constants">Constants</a> section can also be used for type unsafe enums.
Note that global enums are generated into a Java class within whatever package you are using.
C++ enums defined within a C++ class are generated into a static final inner Java class within the Java proxy class.
</p>
<p>
Note that unlike typesafe enums, this approach requires users to mostly use different syntax compared with proper Java enums.
Thus the upgrade path to proper enums provided in JDK 1.5 is more painful.
</p>
<H4><a name="Java_simple_enums">27.3.5.5 Simple enums</a></H4>
<p>
This approach is similar to the type unsafe approach.
Each enum item is also wrapped as a static final integer.
However, these integers are not generated into a class named after the C/C++ enum.
Instead, global enums are generated into the constants interface.
Also, enums defined in a C++ class have their enum items generated directly into the Java proxy class rather than an inner class within the Java proxy class.
In fact, this approach is effectively wrapping the enums as if they were anonymous enums and the resulting code is as per <a href="#Java_anonymous_enums">anonymous enums</a>.
The implementation is in the "enumsimple.swg" file.
</p>
<p>
<b>Compatibility Note:</b>
SWIG-1.3.21 and earlier versions wrapped all enums using this approach.
The type unsafe approach is preferable to this one and this simple approach is only included for backwards compatibility with these earlier versions of SWIG.
</p>
<H3><a name="Java_pointers">27.3.6 Pointers</a></H3>
<p>
C/C++ pointers are fully supported by SWIG. Furthermore, SWIG has no problem working with
incomplete type information. Here is a rather simple interface:
</p>
<div class="code">
<pre>
%module example
FILE *fopen(const char *filename, const char *mode);
int fputs(const char *, FILE *);
int fclose(FILE *);
</pre>
</div>
<p>
When wrapped, you will be able to use the functions in a natural way from Java. For example:
</p>
<div class="code">
<pre>
SWIGTYPE_p_FILE f = example.fopen("junk", "w");
example.fputs("Hello World\n", f);
example.fclose(f);
</pre>
</div>
<p>
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.
Many other SWIG language modules use an encoding of the pointer in a string.
These scripting languages use the SWIG runtime type checker for dynamic type checking as they do not support static type checking by a compiler.
In order to implement static type checking of pointers within Java, they are wrapped by a simple Java class.
In the example above the <tt>FILE *</tt> pointer is wrapped with a <i>type wrapper class </i>
called <tt>SWIGTYPE_p_FILE</tt>.
</p>
<p>
Once obtained, a type wrapper object can be freely passed around to different C functions that
expect to receive an object of that type. The only thing you can't do is
dereference the pointer from Java. Of course, that isn't much of a concern in this example.
</p>
<p>
As much as you might be inclined to modify a pointer value directly
from Java, don't. The value is not necessarily the
same as the logical memory address of the underlying object. The value will
vary depending on the native byte-ordering of the platform (i.e.,
big-endian vs. little-endian).
Most JVMs are 32 bit applications so any JNI code must also be compiled as 32 bit.
The net result is pointers in JNI code are also 32 bits and
are stored in the high order 4 bytes on big-endian machines and in the low order 4 bytes on little-endian machines.
By design it is also not possible to manually cast
a pointer to a new type by using Java casts as it is particularly dangerous especially when
casting C++ objects. If you need to cast a pointer or
change its value, consider writing some helper functions instead. For
example:
</p>
<div class="code">
<pre>
%inline %{
/* C-style cast */
Bar *FooToBar(Foo *f) {
return (Bar *) f;
}
/* C++-style cast */
Foo *BarToFoo(Bar *b) {
return dynamic_cast&lt;Foo*&gt;(b);
}
Foo *IncrFoo(Foo *f, int i) {
return f+i;
}
%}
</pre>
</div>
<p>
Also, if working with C++, you should always try
to use the new C++ style casts. For example, in the above code, the
C-style cast may return a bogus result whereas as the C++-style cast will return
a NULL pointer if the conversion can't be performed.
</p>
<H3><a name="Java_structures">27.3.7 Structures</a></H3>
<p>
If you wrap a C structure, it is wrapped by a Java class with getters and setters for access to the
member variables. For example,
</p>
<div class="code"><pre>
struct Vector {
double x, y, z;
};
</pre></div>
<p>
is used as follows:
</p>
<div class="code"><pre>
Vector v = new Vector();
v.setX(3.5);
v.setY(7.2);
double x = v.getX();
double y = v.getY();
</pre></div>
<p>
The variable setters and getters are also based on the JavaBean design pattern already covered under the Global variables section.
Similar access is provided for unions and the public data members of C++ classes.</p>
<p>
This object is actually an instance of a Java class that has been wrapped around a pointer to the C structure.
This instance doesn't actually do anything--it just serves as a proxy.
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.
Further details about Java proxy classes are covered a little later.
</p>
<p>
<tt>const</tt> members of a structure are read-only. Data members
can also be forced to be read-only using the <tt>%immutable</tt> directive. For example:
</p>
<div class="code">
<pre>
struct Foo {
...
%immutable;
int x; /* Read-only members */
char *name;
%mutable;
...
};
</pre>
</div>
<p>
When <tt>char *</tt> members of a structure are wrapped, the contents are assumed to be
dynamically allocated using <tt>malloc</tt> or <tt>new</tt> (depending on whether or not
SWIG is run with the -c++ option). When the structure member is set, the old contents will be
released and a new value created. If this is not the behavior you want, you will have to use
a typemap (described later).
</p>
<p>
If a structure contains arrays, access to those arrays is managed through pointers. For
example, consider this:
</p>
<div class="code">
<pre>
struct Bar {
int x[16];
};
</pre>
</div>
<p>
If accessed in Java, you will see behavior like this:
</p>
<div class="code">
<pre>
Bar b = new Bar();
SWIGTYPE_p_int x = b.getX();
</pre>
</div>
<p>
This pointer can be passed around to functions that expect to receive
an <tt>int *</tt> (just like C). You can also set the value of an array member using
another pointer. For example:
</p>
<div class="code">
<pre>
Bar b = new Bar();
SWIGTYPE_p_int x = b.getX();
Bar c = new Bar();
c.setX(x); // Copy contents of b.x to c.x
</pre>
</div>
<p>
For array assignment (setters not getters), SWIG copies the entire contents of the array starting with the data pointed
to by <tt>b.x</tt>. In this example, 16 integers would be copied. Like C, SWIG makes
no assumptions about bounds checking---if you pass a bad pointer, you may get a segmentation
fault or access violation.
The default wrapping makes it hard to set or get just one element of the array and so array access from Java is somewhat limited.
This can be changed easily though by using the approach outlined later in the <a href="#Java_c_arrays">Wrapping C arrays with Java arrays</a> and
<a href="#Java_unbounded_c_arrays">Unbounded C Arrays</a> sections.
</p>
<p>
When a member of a structure is itself a structure, it is handled as a
pointer. For example, suppose you have two structures like this:
</p>
<div class="code">
<pre>
struct Foo {
int a;
};
struct Bar {
Foo f;
};
</pre>
</div>
<p>
Now, suppose that you access the <tt>f</tt> member of <tt>Bar</tt> like this:
</p>
<div class="code">
<pre>
Bar b = new Bar();
Foo x = b.getF();
</pre>
</div>
<p>
In this case, <tt>x</tt> is a pointer that points to the <tt>Foo</tt> that is inside <tt>b</tt>.
This is the same value as generated by this C code:
</p>
<div class="code">
<pre>
Bar b;
Foo *x = &amp;b-&gt;f; /* Points inside b */
</pre>
</div>
<p>
Because the pointer points inside the structure, you can modify the contents and
everything works just like you would expect. For example:
</p>
<div class="code">
<pre>
Bar b = new Bar();
b.getF().setA(3); // Modify b.f.a
Foo x = b.getF();
x.setA(3); // Modify x.a - this is the same as b.f.a
</pre>
</div>
<H3><a name="Java_classes">27.3.8 C++ classes</a></H3>
<p>
C++ classes are wrapped by Java classes as well. For example, if you have this class,
</p>
<div class="code"><pre>
class List {
public:
List();
~List();
int search(char *item);
void insert(char *item);
void remove(char *item);
char *get(int n);
int length;
};
</pre></div>
<p>
you can use it in Java like this:
</p>
<div class="code"><pre>
List l = new List();
l.insert("Ale");
l.insert("Stout");
l.insert("Lager");
String item = l.get(2);
int length = l.getLength();
</pre></div>
<p>
Class data members are accessed in the same manner as C structures.
</p>
<p>
Static class members are unsurprisingly wrapped as static members of the Java class:
</p>
<div class="code">
<pre>
class Spam {
public:
static void foo();
static int bar;
};
</pre>
</div>
<p>
The static members work like any other Java static member:
</p>
<div class="code">
<pre>
Spam.foo();
int bar = Spam.getBar();
</pre>
</div>
<H3><a name="Java_inheritance">27.3.9 C++ inheritance</a></H3>
<p>
SWIG is fully aware of issues related to C++ inheritance. Therefore, if you have
classes like this
</p>
<div class="code">
<pre>
class Foo {
...
};
class Bar : public Foo {
...
};
</pre>
</div>
<p>
those classes are wrapped into a hierarchy of Java classes that reflect the same inheritance
structure:
</p>
<div class="code">
<pre>
Bar b = new Bar();
Class c = b.getClass();
System.out.println(c.getSuperclass().getName());
</pre>
</div>
<p>
will of course display:
</p>
<div class="code"><pre>
Foo
</pre></div>
<p>
Furthermore, if you have functions like this
</p>
<div class="code">
<pre>
void spam(Foo *f);
</pre>
</div>
<p>
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>.
</p>
<p>
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.
</p>
<H3><a name="Java_pointers_refs_arrays">27.3.10 Pointers, references, arrays and pass by value</a></H3>
<p>
In C++, there are many different ways a function might receive
and manipulate objects. For example:
</p>
<div class="code">
<pre>
void spam1(Foo *x); // Pass by pointer
void spam2(Foo &amp;x); // Pass by reference
void spam3(Foo x); // Pass by value
void spam4(Foo x[]); // Array of objects
</pre>
</div>
<p>
In Java, there is no detailed distinction like this--specifically,
there are only instances of classes. There are no pointers nor references.
Because of this, SWIG unifies all of these types
together in the wrapper code. For instance, if you actually had the
above functions, it is perfectly legal to do this from Java:
</p>
<div class="code">
<pre>
Foo f = new Foo(); // Create a Foo
example.spam1(f); // Ok. Pointer
example.spam2(f); // Ok. Reference
example.spam3(f); // Ok. Value.
example.spam4(f); // Ok. Array (1 element)
</pre>
</div>
<p>
Similar behavior occurs for return values. For example, if you had
functions like this,
</p>
<div class="code">
<pre>
Foo *spam5();
Foo &amp;spam6();
Foo spam7();
</pre>
</div>
<p>
then all three functions will return a pointer to some <tt>Foo</tt> object.
Since the third function (spam7) returns a value, newly allocated memory is used
to hold the result and a pointer is returned (Java will release this memory
when the returned object's finalizer is run by the garbage collector).
</p>
<H4><a name="Java_null_pointers">27.3.10.1 Null pointers</a></H4>
<p>
Working with null pointers is easy.
A Java <tt>null</tt> can be used whenever a method expects a proxy class or typewrapper class.
However, it is not possible to pass null to C/C++ functions that take parameters by value or by reference.
If you try you will get a NullPointerException.
</p>
<div class="code">
<pre>
example.spam1(null); // Pointer - ok
example.spam2(null); // Reference - NullPointerException
example.spam3(null); // Value - NullPointerException
example.spam4(null); // Array - ok
</pre>
</div>
<p>
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.
The converse also occurs, that is, NULL pointers are translated into <tt>null</tt> Java objects when returned from a C/C++ function.
</p>
<H3><a name="Java_overloaded_functions">27.3.11 C++ overloaded functions</a></H3>
<p>
C++ overloaded functions, methods, and constructors are mostly supported by SWIG. For example,
if you have two functions like this:
</p>
<div class="code">
<pre>
%module example
void foo(int);
void foo(char *c);
</pre>
</div>
<p>
You can use them in Java in a straightforward manner:
</p>
<div class="code">
<pre>
example.foo(3); // foo(int)
example.foo("Hello"); // foo(char *c)
</pre>
</div>
<p>
Similarly, if you have a class like this,
</p>
<div class="code">
<pre>
class Foo {
public:
Foo();
Foo(const Foo &amp;);
...
};
</pre>
</div>
<p>
you can write Java code like this:
</p>
<div class="code">
<pre>
Foo f = new Foo(); // Create a Foo
Foo g = new Foo(f); // Copy f
</pre>
</div>
<p>
Overloading support is not quite as flexible as in C++. Sometimes there are methods that SWIG
cannot disambiguate as there can be more than one C++ type mapping onto a single Java type. For example:
</p>
<div class="code">
<pre>
void spam(int);
void spam(unsigned short);
</pre>
</div>
<p>
Here both int and unsigned short map onto a Java int.
Here is another example:
</p>
<div class="code">
<pre>
void foo(Bar *b);
void foo(Bar &amp;b);
</pre>
</div>
<p>
If declarations such as these appear, you will get a warning message like this:
</p>
<div class="code">
<pre>
example.i:12: Warning 515: Overloaded method spam(unsigned short) ignored.
Method spam(int) at example.i:11 used.
</pre>
</div>
<p>
To fix this, you either need to either <a href="SWIG.html#SWIG_rename_ignore">rename or ignore</a> one of the methods. For example:
</p>
<div class="code">
<pre>
%rename(spam_ushort) spam(unsigned short);
...
void spam(int);
void spam(unsigned short); // Now renamed to spam_ushort
</pre>
</div>
<p>
or
</p>
<div class="code">
<pre>
%ignore spam(unsigned short);
...
void spam(int);
void spam(unsigned short); // Ignored
</pre>
</div>
<H3><a name="Java_default_arguments">27.3.12 C++ default arguments</a></H3>
<p>
Any function with a default argument is wrapped by generating an additional function for each argument that is defaulted.
For example, if we have the following C++:
</p>
<div class="code">
<pre>
%module example
void defaults(double d=10.0, int i=0);
</pre>
</div>
<p>
The following methods are generated in the Java module class:
</p>
<div class="code">
<pre>
public class example {
public static void defaults(double d, int i) { ... }
public static void defaults(double d) { ... }
public static void defaults() { ... }
}
</pre>
</div>
<p>
It is as if SWIG had parsed three separate overloaded methods.
The same approach is taken for static methods, constructors and member methods.
</p>
<p>
<b>Compatibility note:</b> Versions of SWIG prior to SWIG-1.3.23 wrapped these with a
single wrapper method and so the default values could not be taken advantage of from Java.
Further details on default arguments and how to restore this approach are given in the more general
<a href="SWIGPlus.html#SWIGPlus_default_args">Default arguments</a> section.
</p>
<H3><a name="Java_namespaces">27.3.13 C++ namespaces</a></H3>
<p>
SWIG is aware of named C++ namespaces and they can be mapped to Java packages, however,
the default wrapping flattens the namespaces, effectively ignoring them.
So by default, the namespace names do not appear in
the module nor do namespaces result in a module that is broken up into
submodules or packages. For example, if you have a file like this,
</p>
<div class="code">
<pre>
%module example
namespace foo {
int fact(int n);
struct Vector {
double x, y, z;
};
};
</pre>
</div>
<p>
it works in Java as follows:
</p>
<div class="code">
<pre>
int f = example.fact(3);
Vector v = new Vector();
v.setX(3.4);
double y = v.getY();
</pre>
</div>
<p>
If your program has more than one namespace, name conflicts (if any) can be resolved using <tt>%rename</tt>
For example:
</p>
<div class="code">
<pre>
%rename(Bar_spam) Bar::spam;
namespace Foo {
int spam();
}
namespace Bar {
int spam();
}
</pre>
</div>
<p>
If you have more than one namespace and you want to keep their
symbols separate, consider wrapping them as separate SWIG modules.
Each SWIG module can be placed into a separate package.
</p>
<p>
The default behaviour described above can be improved via the <a href="SWIGPlus.html#SWIGPlus_nspace">nspace feature</a>.
Note that it only works for classes, structs, unions and enums declared within a named C++ namespace.
When the nspace feature is used, the C++ namespaces are converted into Java packages of the same name.
Proxy classes are thus declared within a package and this proxy makes numerous calls to the JNI intermediary class which is declared in the unnamed package by default.
As Java does not support types declared in a named package accessing types declared in an unnamed package, the <tt>-package</tt> commandline option described earlier generally should be used to provide a parent package.
So if SWIG is run using the <tt>-package com.myco</tt> option, a wrapped class, <tt>MyWorld::Material::Color</tt>, can then be accessed as <tt>com.myco.MyWorld.Material.Color</tt>.
If you don't specify a package, you will get the following warning:
</p>
<div class="shell">
<pre>
example.i:16: Warning 826: The nspace feature is used on 'MyWorld::Material::Color' without -package. The generated code
may not compile as Java does not support types declared in a named package accessing types declared in an unnamed package.
</pre>
</div>
<p>
If it is undesirable to have a single top level package, the nspace feature may be used without the <tt>-package</tt> commandline option
(and the resulting warning ignored) if all of the types exposed using SWIG are placed in a package using the nspace feature and the
'jniclasspackage' pragma is used to specify a package for the JNI intermediary class.
</p>
<p>
If the resulting use of the nspace feature and hence packages results in a proxy class in one package deriving or using a proxy class from another package,
you will need to open up the visibility for the pointer constructor and <tt>getCPtr</tt> method from the default 'protected' to 'public' with the <tt>SWIG_JAVABODY_PROXY</tt> macro. See <a href="#Java_code_typemaps">Java code typemaps</a>.
</p>
<H3><a name="Java_templates">27.3.14 C++ templates</a></H3>
<p>
C++ templates don't present a huge problem for SWIG. However, in order
to create wrappers, you have to tell SWIG to create wrappers for a particular
template instantiation. To do this, you use the <tt>%template</tt> directive.
For example:
</p>
<div class="code">
<pre>
%module example
%{
#include &lt;utility&gt;
%}
template&lt;class T1, class T2&gt;
struct pair {
typedef T1 first_type;
typedef T2 second_type;
T1 first;
T2 second;
pair();
pair(const T1&amp;, const T2&amp;);
~pair();
};
%template(pairii) pair&lt;int, int&gt;;
</pre>
</div>
<p>
In Java:
</p>
<div class="code">
<pre>
pairii p = new pairii(3, 4);
int first = p.getFirst();
int second = p.getSecond();
</pre>
</div>
<p>
Obviously, there is more to template wrapping than shown in this example.
More details can be found in the <a href="SWIGPlus.html#SWIGPlus">SWIG and C++</a> chapter.
</p>
<H3><a name="Java_smart_pointers">27.3.15 C++ Smart Pointers</a></H3>
<H4><a name="Java_smart_pointers_shared_ptr">27.3.15.1 The shared_ptr Smart Pointer</a></H4>
<p>
The C++11 standard provides <tt>std::shared_ptr</tt> which was derived from the Boost
implementation, <tt>boost::shared_ptr</tt>.
Both of these are available for Java in the SWIG library and usage is outlined
in the <a href="Library.html#Library_std_shared_ptr">shared_ptr smart pointer</a> library section.
</p>
<H4><a name="Java_smart_pointers_generic">27.3.15.2 Generic Smart Pointers</a></H4>
<p>
In certain C++ programs, it is common to use classes that have been wrapped by
so-called "smart pointers." Generally, this involves the use of a template class
that implements <tt>operator-&gt;()</tt> like this:
</p>
<div class="code">
<pre>
template&lt;class T&gt; class SmartPtr {
...
T *operator-&gt;();
...
}
</pre>
</div>
<p>
Then, if you have a class like this,
</p>
<div class="code">
<pre>
class Foo {
public:
int x;
int bar();
};
</pre>
</div>
<p>
A smart pointer would be used in C++ as follows:
</p>
<div class="code">
<pre>
SmartPtr&lt;Foo&gt; p = CreateFoo(); // Created somehow (not shown)
...
p-&gt;x = 3; // Foo::x
int y = p-&gt;bar(); // Foo::bar
</pre>
</div>
<p>
To wrap this in Java, simply tell SWIG about the <tt>SmartPtr</tt> class and the low-level
<tt>Foo</tt> object. Make sure you instantiate <tt>SmartPtr</tt> using <tt>%template</tt> if necessary.
For example:
</p>
<div class="code">
<pre>
%module example
...
%template(SmartPtrFoo) SmartPtr&lt;Foo&gt;;
...
</pre>
</div>
<p>
Now, in Java, everything should just "work":
</p>
<div class="code">
<pre>
SmartPtrFoo p = example.CreateFoo(); // Create a smart-pointer somehow
p.setX(3); // Foo::x
int y = p.bar(); // Foo::bar
</pre>
</div>
<p>
If you ever need to access the underlying pointer returned by <tt>operator-&gt;()</tt> itself,
simply use the <tt>__deref__()</tt> method. For example:
</p>
<div class="code">
<pre>
Foo f = p.__deref__(); // Returns underlying Foo *
</pre>
</div>
<H2><a name="Java_further_details">27.4 Further details on the generated Java classes</a></H2>
<p>
In the previous section, a high-level view of Java wrapping was
presented. A key component of this wrapping is that structures and
classes are wrapped by Java proxy classes and type wrapper classes are used
in situations where no proxies are generated. This provides a very
natural, type safe Java interface to the C/C++ code and fits in with the Java programming paradigm.
However, a number of low-level details were omitted. This section provides a brief overview
of how the proxy classes work and then covers the type wrapper classes.
Finally enum classes are covered.
First, the crucial intermediary JNI class is considered.
</p>
<H3><a name="Java_imclass">27.4.1 The intermediary JNI class</a></H3>
<p>
In the <a href="SWIG.html#SWIG">"SWIG basics"</a> and <a href="SWIGPlus.html#SWIGPlus">"SWIG and C++"</a> chapters,
details of low-level structure and class wrapping are described. To summarize those chapters, if you
have a global function and class like this
</p>
<div class="code">
<pre>
class Foo {
public:
int x;
int spam(int num, Foo* foo);
};
void egg(Foo* chips);
</pre>
</div>
<p>
then SWIG transforms the class into a set of low-level procedural wrappers.
These procedural wrappers essentially perform the equivalent of this C++ code:
</p>
<div class="code">
<pre>
Foo *new_Foo() {
return new Foo();
}
void delete_Foo(Foo *f) {
delete f;
}
int Foo_x_get(Foo *f) {
return f-&gt;x;
}
void Foo_x_set(Foo *f, int value) {
f-&gt;x = value;
}
int Foo_spam(Foo *f, int num, Foo* foo) {
return f-&gt;spam(num, foo);
}
</pre>
</div>
<p>
These procedural function names don't actually exist, but their functionality appears inside the generated
JNI functions. The JNI functions have to follow a particular naming convention so the function names are actually:
</p>
<div class="code">
<pre>
SWIGEXPORT jlong JNICALL Java_exampleJNI_new_1Foo(JNIEnv *jenv, jclass jcls);
SWIGEXPORT void JNICALL Java_exampleJNI_delete_1Foo(JNIEnv *jenv, jclass jcls,
jlong jarg1);
SWIGEXPORT void JNICALL Java_exampleJNI_Foo_1x_1set(JNIEnv *jenv, jclass jcls,
jlong jarg1, jobject jarg1_, jint jarg2);
SWIGEXPORT jint JNICALL Java_exampleJNI_Foo_1x_1get(JNIEnv *jenv, jclass jcls,
jlong jarg1, jobject jarg1_);
SWIGEXPORT jint JNICALL Java_exampleJNI_Foo_1spam(JNIEnv *jenv, jclass jcls,
jlong jarg1, jobject jarg1_, jint jarg2,
jlong jarg3, jobject jarg3_);
SWIGEXPORT void JNICALL Java_exampleJNI_egg(JNIEnv *jenv, jclass jcls,
jlong jarg1, jobject jarg1_);
</pre>
</div>
<p>
For every JNI C function there has to be a static native Java function. These appear in the intermediary JNI class:
</p>
<div class="code">
<pre>
class exampleJNI {
public final static native long new_Foo();
public final static native void delete_Foo(long jarg1);
public final static native void Foo_x_set(long jarg1, Foo jarg1_, int jarg2);
public final static native int Foo_x_get(long jarg1, Foo jarg1_);
public final static native int Foo_spam(long jarg1, Foo jarg1_, int jarg2,
long jarg3, Foo jarg3_);
public final static native void egg(long jarg1, Foo jarg1_);
}
</pre>
</div>
<p>
This class contains the complete Java - C/C++ interface so all function calls go via this class.
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="#Java_type_wrapper_classes">type wrapper classes</a> and <a href="#Java_module_class">module class</a>, it is known as the intermediary JNI class.
</p>
<p>
You may notice that SWIG uses a Java long wherever a pointer or class object needs to be marshalled across the Java-C/C++ boundary.
This approach leads to minimal JNI code which makes for better performance as JNI code involves a lot of string manipulation.
SWIG favours generating Java code over JNI code as Java code is compiled into byte code and avoids the costly string operations needed in JNI code.
This approach has a downside though as the proxy class might get collected before the native method has completed.
You might notice above that there is an additional parameters with a underscore postfix, eg <tt>jarg1_</tt>.
These are added in order to prevent <a href="#Java_pgcpp">premature garbage collection when marshalling proxy classes</a>.
</p>
<p>
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.
</p>
<a name="Java_module_directive"></a>
<p>
The name of the intermediary JNI class can be changed from its default, that is, the module name with JNI appended after it.
The module directive attribute <tt>jniclassname</tt> is used to achieve this:
</p>
<div class="code">
<pre>
%module (jniclassname="name") modulename
</pre>
</div>
<p>
If <tt>name</tt> is the same as <tt>modulename</tt> then the module class name gets changed
from <tt>modulename</tt> to <tt>modulenameModule</tt>.
</p>
<H4><a name="Java_imclass_pragmas">27.4.1.1 The intermediary JNI class pragmas</a></H4>
<p>
The intermediary JNI class can be tailored through the use of pragmas, but is not commonly done. The pragmas for this class are:
</p>
<table BORDER summary="Intermediary JNI class pragmas">
<tr VALIGN=TOP>
<td><b>Pragma</b></td>
<td><b>Description</b></td>
</tr>
<tr>
<td>jniclassbase </td> <td>Base class for the intermediary JNI class</td>
</tr>
<tr>
<td>jniclasspackage </td> <td>Package in which to place the intermediary JNI class</td>
</tr>
<tr>
<td>jniclassclassmodifiers </td> <td>Class modifiers and class type for the intermediary JNI class</td>
</tr>
<tr>
<td>jniclasscode </td> <td>Java code is copied verbatim into the intermediary JNI class</td>
</tr>
<tr>
<td>jniclassimports </td> <td>Java code, usually one or more import statements, placed before the intermediary JNI class definition</td>
</tr>
<tr>
<td>jniclassinterfaces </td> <td>Comma separated interface classes for the intermediary JNI class</td>
</tr>
</table>
<p>
The pragma code appears in the generated intermediary JNI class where you would expect:
</p>
<div class="code">
<pre>
[ jniclassimports pragma ]
[ jniclassclassmodifiers pragma ] jniclassname extends [ jniclassbase pragma ]
implements [ jniclassinterfaces pragma ] {
[ jniclasscode pragma ]
... SWIG generated native methods ...
}
</pre>
</div>
<p>
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:
</p>
<div class="code">
<pre>
%pragma(java) jniclasscode=%{
static {
try {
System.loadLibrary("example");
} catch (UnsatisfiedLinkError e) {
System.err.println("Native code library failed to load. \n" + e);
System.exit(1);
}
}
%}
</pre>
</div>
<p>
Pragmas will take either <tt>""</tt> or <tt>%{ %}</tt> as delimiters.
For example, let's change the intermediary JNI class access to just the default package-private access.
</p>
<div class="code">
<pre>
%pragma(java) jniclassclassmodifiers="class"
</pre>
</div>
<p>
All the methods in the intermediary JNI class will then not be callable outside of the package as the method modifiers have been changed from public access to default access. This is useful if you want to prevent users calling these low level functions.
</p>
<H3><a name="Java_module_class">27.4.2 The Java module class</a></H3>
<p>
All global functions and variable getters/setters appear in the module class. For our example, there is just one function:
</p>
<div class="code">
<pre>
public class example {
public static void egg(Foo chips) {
exampleJNI.egg(Foo.getCPtr(chips), chips);
}
}
</pre>
</div>
<p>
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:
</p>
<div class="code">
<pre>
example.egg(new Foo());
</pre>
</div>
<p>
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.
</p>
<H4><a name="Java_module_class_pragmas">27.4.2.1 The Java module class pragmas</a></H4>
<p>
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:
</p>
<table BORDER summary="Java module class pragmas">
<tr VALIGN=TOP>
<td><b>Pragma</b></td>
<td><b>Description</b></td>
</tr>
<tr>
<td>modulebase </td> <td>Base class for the module class</td>
</tr>
<tr>
<td>moduleclassmodifiers </td> <td>Class modifiers and class type for the module class</td>
</tr>
<tr>
<td>modulecode </td> <td>Java code is copied verbatim into the module class</td>
</tr>
<tr>
<td>moduleimports </td> <td>Java code, usually one or more import statements, placed before the module class definition</td>
</tr>
<tr>
<td>moduleinterfaces </td> <td>Comma separated interface classes for the module class</td>
</tr>
</table>
<p>
The pragma code appears in the generated module class like this:
</p>
<div class="code">
<pre>
[ moduleimports pragma ]
[ modulemodifiers pragma ] modulename extends [ modulebase pragma ]
implements [ moduleinterfaces pragma ] {
[ modulecode pragma ]
... SWIG generated wrapper functions ...
}
</pre>
</div>
<p>
See <a href="#Java_imclass_pragmas">The intermediary JNI class pragmas</a> section for further details on using pragmas.
</p>
<H3><a name="Java_proxy_classes">27.4.3 Java proxy classes</a></H3>
<p>
A Java proxy class is generated for each structure, union or C++ class that is wrapped.
Proxy classes have also been called <a href="http://java.sun.com/docs/books/jni/html/stubs.html">peer classes</a>.
The default proxy class for our previous example looks like this:
</p>
<div class="code">
<pre>
public class Foo {
private transient long swigCPtr;
protected transient boolean swigCMemOwn;
protected Foo(long cPtr, boolean cMemoryOwn) {
swigCMemOwn = cMemoryOwn;
swigCPtr = cPtr;
}
protected static long getCPtr(Foo obj) {
return (obj == null) ? 0 : obj.swigCPtr;
}
protected void finalize() {
delete();
}
public synchronized void delete() {
if(swigCPtr != 0 &amp;&amp; swigCMemOwn) {
swigCMemOwn = false;
exampleJNI.delete_Foo(swigCPtr);
}
swigCPtr = 0;
}
public void setX(int value) {
exampleJNI.Foo_x_set(swigCPtr, this, value);
}
public int getX() {
return exampleJNI.Foo_x_get(swigCPtr, this);
}
public int spam(int num, Foo foo) {
return exampleJNI.Foo_spam(swigCPtr, this, num, Foo.getCPtr(foo), foo);
}
public Foo() {
this(exampleJNI.new_Foo(), true);
}
}
</pre>
</div>
<p>
This class merely holds a pointer to the underlying C++ object (<tt>swigCPtr</tt>).
It also contains all the methods in the C++ class it is proxying plus getters and setters for public
member variables. These functions call the native methods in the intermediary JNI class.
The advantage of having this extra layer is the type safety that the proxy class functions offer.
It adds static type checking which leads to fewer surprises at runtime.
For example, you can see that if you attempt to use the <tt>spam()</tt>
function it will only compile when the parameters passed are an <tt>int</tt> and a <tt>Foo</tt>.
From a user's point of view, it makes the class work as if it were a Java class:
</p>
<div class="code">
<pre>
Foo f = new Foo();
f.setX(3);
int y = f.spam(5, new Foo());
</pre>
</div>
<H4><a name="Java_memory_management">27.4.3.1 Memory management</a></H4>
<p>
Each proxy class has an ownership flag <tt>swigCMemOwn</tt>. The value of this
flag determines who is responsible for deleting the underlying C++ object. If set to <tt>true</tt>,
the proxy class's finalizer will destroy the C++ object when the proxy class is
garbage collected. If set to false, then the destruction of the proxy class has no effect on the C++ object.
</p>
<p>
When an object is created by a constructor or returned by value, Java automatically takes
ownership of the result.
On the other hand, when pointers or references are returned to Java, there is often no way to know where
they came from. Therefore, the ownership is set to false. For example:
</p>
<div class="code">
<pre>
class Foo {
public:
Foo();
Foo bar1();
Foo &amp;bar2();
Foo *bar2();
};
</pre>
</div>
<p>
In Java:
</p>
<div class="code">
<pre>
Foo f = new Foo(); // f.swigCMemOwn = true
Foo f1 = f.bar1(); // f1.swigCMemOwn = true
Foo f2 = f.bar2(); // f2.swigCMemOwn = false
Foo f3 = f.bar3(); // f3.swigCMemOwn = false
</pre>
</div>
<p>
This behavior for pointers and references is especially important for classes that act as containers.
For example, if a method returns a pointer to an object
that is contained inside another object, you definitely don't want
Java to assume ownership and destroy it!
</p>
<p>
For the most part, memory management issues remain hidden. However,
there are situations where you might have to manually
change the ownership of an object. For instance, consider code like this:
</p>
<div class="code">
<pre>
class Obj {};
class Node {
Obj *value;
public:
void set_value(Obj *v) { value = v; }
};
</pre>
</div>
<p>
Now, consider the following Java code:
</p>
<div class="code">
<pre>
Node n = new Node(); // Create a node
{
Obj o = new Obj(); // Create an object
n.set_value(o); // Set value
} // o goes out of scope
</pre>
</div>
<p>
In this case, the Node <tt>n</tt> is holding a reference to
<tt>o</tt> internally. However, SWIG has no way to know that this
has occurred. The Java proxy class still thinks that it has ownership of
<tt>o</tt>. As <tt>o</tt> has gone out of scope, it could be garbage collected in which case the C++ destructor
will be invoked and <tt>n</tt> will then be holding a stale-pointer to <tt>o</tt>. If
you're lucky, you will only get a segmentation fault.
</p>
<p>
To work around this, the ownership flag of <tt>o</tt> needs changing to <tt>false</tt>.
The ownership flag is a private member variable of the proxy class so this is not possible without some customization of the proxy class.
This can be achieved by using a typemap to customise the proxy class with pure Java code as detailed later in the section on
<a href="#Java_typemaps">Java typemaps</a>.
</p>
<p>
Sometimes a function will create memory and return a pointer to a newly allocated object.
SWIG has no way of knowing this so by default the proxy class does not manage the returned object.
However, you can tell the proxy class to manage the memory if you specify the <tt>%newobject</tt> directive. Consider:
</p>
<div class="code">
<pre>
class Obj {...};
class Factory {
public:
static Obj *createObj() { return new Obj(); }
};
</pre>
</div>
<p>
If we call the factory function, then we have to manually delete the memory:
</p>
<div class="code">
<pre>
Obj obj = Factory.createObj(); // obj.swigCMemOwn = false
...
obj.delete();
</pre>
</div>
<p>
Now add in the %newobject directive:
</p>
<div class="code">
<pre>
%newobject Factory::createObj();
class Obj {...};
class Factory {
public:
static Obj *createObj() { return new Obj(); }
};
</pre>
</div>
<p>
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.
</p>
<div class="code">
<pre>
Obj obj = Factory.createObj(); // obj.swigCMemOwn = true;
...
</pre>
</div>
<p>
Some memory management issues are quite tricky to fix and may only be noticeable after using for a long time.
One such issue is premature garbage collection of an object created from Java and resultant usage from C++ code.
The section on typemap examples cover two such scenarios,
<a href="#Java_memory_management_objects">Memory management for objects passed to the C++ layer</a>
and
<a href="#Java_memory_management_member_variables">Memory management when returning references to member variables</a>
</p>
<H4><a name="Java_inheritance_mirroring">27.4.3.2 Inheritance</a></H4>
<p>
Java proxy classes will mirror C++ inheritance chains. For example, given the base class <tt>Base</tt> and its derived class <tt>Derived</tt>:
</p>
<div class="code"><pre>
class Base {
public:
virtual double foo();
};
class Derived : public Base {
public:
virtual double foo();
};
</pre></div>
<p>
The base class is generated much like any other proxy class seen so far:
</p>
<div class="code"><pre>
public class Base {
private transient long swigCPtr;
protected transient boolean swigCMemOwn;
protected Base(long cPtr, boolean cMemoryOwn) {
swigCMemOwn = cMemoryOwn;
swigCPtr = cPtr;
}
protected static long getCPtr(Base obj) {
return (obj == null) ? 0 : obj.swigCPtr;
}
protected void finalize() {
delete();
}
public synchronized void delete() {
if(swigCPtr != 0 &amp;&amp; swigCMemOwn) {
swigCMemOwn = false;
exampleJNI.delete_Base(swigCPtr);
}
swigCPtr = 0;
}
public double foo() {
return exampleJNI.Base_foo(swigCPtr, this);
}
public Base() {
this(exampleJNI.new_Base(), true);
}
}
</pre></div>
<p>
The <tt>Derived</tt> class extends <tt>Base</tt> mirroring the C++ class inheritance hierarchy.
</p>
<div class="code"><pre>
public class Derived extends Base {
private transient long swigCPtr;
protected Derived(long cPtr, boolean cMemoryOwn) {
super(exampleJNI.SWIGDerivedUpcast(cPtr), cMemoryOwn);
swigCPtr = cPtr;
}
protected static long getCPtr(Derived obj) {
return (obj == null) ? 0 : obj.swigCPtr;
}
protected void finalize() {
delete();
}
public synchronized void delete() {
if(swigCPtr != 0 &amp;&amp; swigCMemOwn) {
swigCMemOwn = false;
exampleJNI.delete_Derived(swigCPtr);
}
swigCPtr = 0;
super.delete();
}
public double foo() {
return exampleJNI.Derived_foo(swigCPtr, this);
}
public Derived() {
this(exampleJNI.new_Derived(), true);
}
}
</pre></div>
<p>
Note the memory ownership is controlled by the base class.
However each class in the inheritance hierarchy has its own pointer value which is obtained during construction.
The <tt>SWIGDerivedUpcast()</tt> call converts the pointer from a <tt>Derived *</tt> to a <tt>Base *</tt>.
This is a necessity as C++ compilers are free to implement pointers in the inheritance hierarchy with different values.
</p>
<p>
It is of course possible to extend <tt>Base</tt> using your own Java classes.
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>.
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.
However, true cross language polymorphism can be achieved using the <a href="#Java_directors">directors</a> feature.
</p>
<H4><a name="Java_proxy_classes_gc">27.4.3.3 Proxy classes and garbage collection</a></H4>
<p>
By default each proxy class has a <tt>delete()</tt> and a <tt>finalize()</tt> method.
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.
The idea is for <tt>delete()</tt> to be called when you have finished with the C/C++ object.
Ideally you need not call <tt>delete()</tt>, but rather leave it to the garbage collector to call it from the finalizer.
When a program exits, the garbage collector does not guarantee to call all finalizers.
An insight into the reasoning behind this can be obtained from <a href="https://www.hpl.hp.com/techreports/2002/HPL-2002-335.html">Hans Boehm's Destructors, Finalizers, and Synchronization</a> paper.
Depending on what the finalizers do and which operating system you use, this may or may not be a problem.
</p>
<p>
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.
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.
In Windows and Unix all memory that a process uses is returned to the system on exit, 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 with long running programs the garbage collector will eventually run, thereby calling any unreferenced object's finalizers.
</p>
<p>
Some not so ideal solutions are:
</p>
<ol>
<li><p>
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 documentation says: </p>
<div class="code"><i>
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.
</i></div>
<p>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="https://www.oracle.com/technetwork/java/index.html">Java web site</a> and search for <tt>runFinalizersOnExit</tt>.
</p></li>
<li><p>
From jdk1.3 onwards a new function, <tt>addShutdownHook()</tt>, 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 <tt>main()</tt> function: </p>
<div class="code"><pre>
static {
Runtime.getRuntime().addShutdownHook(
new Thread() {
public void run() { System.gc(); System.runFinalization(); }
}
);
}
</pre></div>
<p>Although this usually works, the documentation doesn't guarantee that <tt>runFinalization()</tt> will actually call the finalizers.
As 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.</p>
</li>
<li>
<p>Call the <tt>delete()</tt> function manually which will immediately invoke the C++ destructor.
As a suggestion it may be a good idea to set the object to null so that should the object be inadvertently 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:</p>
<div class="code"><pre>
A myA = new A();
// use myA ...
myA.delete();
// any use of myA here would crash the JVM
myA=null;
// any use of myA here would cause a Java null pointer exception to be thrown
</pre></div>
<p>
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.
</p>
</li>
<li>
<p>
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.
The section on <a href="#Java_typemaps">Java typemaps</a> details how to specify a pure Java base class.
</p>
</li>
</ol>
<p>
See the <a href="http://www.devx.com/Java/Article/30192">How to Handle Java Finalization's Memory-Retention Issues</a> article for alternative approaches to managing memory by avoiding finalizers altogether.
</p>
<H4><a name="Java_pgcpp">27.4.3.4 The premature garbage collection prevention parameter for proxy class marshalling</a></H4>
<p>
As covered earlier, the C/C++ struct/class pointer is stored in the proxy class as a Java long and when needed is passed
into the native method where it is cast into the appropriate type.
This approach provides very fast marshalling but could be susceptible to premature garbage collection.
Consider the following C++ code:
</p>
<div class="code"><pre>
class Wibble {
};
void wobble(Wibble &amp;w);
</pre></div>
<p>
The module class contains the Java wrapper for the global <tt>wobble</tt> method:
</p>
<div class="code"><pre>
public class example {
...
public static void wobble(Wibble w) {
exampleJNI.wobble(Wibble.getCPtr(w), w);
}
}
</pre></div>
<p>
where <tt>example</tt> is the name of the module.
All native methods go through the intermediary class which has the native method declared as such:
</p>
<div class="code"><pre>
public class exampleJNI {
...
public final static native void wobble(long jarg1, Wibble jarg1_);
}
</pre></div>
<p>
The second parameter, <tt>jarg1_</tt>, is the premature garbage collection prevention parameter and is added to the native method parameter list whenever a C/C++ struct or class is marshalled as a Java long.
In order to understand why, consider the alternative where the intermediary class method is declared without the additional parameter:
</p>
<div class="code"><pre>
public class exampleJNI {
...
public final static native void wobble(long jarg1);
}
</pre></div>
<p>
and the following simple call to <tt>wobble</tt>:
</p>
<div class="code"><pre>
{
Wibble w = new Wibble();
example.wobble(w);
}
</pre></div>
<p>
The hotspot compiler effectively sees something like:
</p>
<div class="code"><pre>
{
Wibble w = new Wibble();
long w_ptr = Wibble.getCPtr(w);
// w is no longer reachable
exampleJNI.wobble(w_ptr);
}
</pre></div>
<p>
The <tt>Wibble</tt> object is no longer reachable after the point shown as in this bit of code, the <tt>Wibble</tt> object is not referenced again after this point.
This means that it is a candidate for garbage collection.
Should <tt>wobble</tt> be a long running method, it is quite likely that the finalizer for the <tt>Wibble</tt> instance will be called.
This in turn will call its underlying C++ destructor which
is obviously disastrous while the method <tt>wobble</tt> is running using this object.
Even if <tt>wobble</tt> is not a long running method, it is possible for the <tt>Wibble</tt> instance to be finalized.
By passing the <tt>Wibble</tt> instance into the native method, it will not be finalized as the JVM guarantees not to
finalize any objects until the native method returns.
Effectively, the code then becomes
</p>
<div class="code"><pre>
{
Wibble w = new Wibble();
long w_ptr = Wibble.getCPtr(w);
exampleJNI.wobble(w_ptr, w);
// w is no longer reachable
}
</pre></div>
<p>
and therefore there is no possibility of premature garbage collection. In practice, this premature garbage collection was only ever observed in Sun's server JVM from jdk-1.3 onwards and in Sun's client JVM from jdk-1.6 onwards.
</p>
<p>
The premature garbage collection prevention parameter for proxy classes is generated by default whenever proxy classes are passed by value, reference or with a pointer.
The implementation for this extra parameter generation requires the "jtype" typemap to contain <tt>long</tt> and the "jstype" typemap to contain the name of a proxy class.
</p>
<p>
The additional parameter does impose a slight performance overhead and the parameter generation can be suppressed globally with the <tt>-nopgcpp</tt> commandline option.
More selective suppression is possible with the 'nopgcpp' attribute in the "jtype" <a href="#Java_typemaps">Java typemap</a>.
The attribute is a flag and so should be set to "1" to enable the suppression, or it can be omitted or set to "0" to disable.
For example:
</p>
<div class="code"><pre>
%typemap(jtype, nopgcpp="1") Wibble &amp; "long"
</pre></div>
<p>
<b>Compatibility note:</b> The generation of this additional parameter did not occur in versions prior to SWIG-1.3.30.
</p>
<H4><a name="Java_multithread_libraries">27.4.3.5 Single threaded applications and thread safety</a></H4>
<p>
Single threaded Java applications using JNI need to consider thread safety.
The same applies for the C# module where the .NET wrappers use PInvoke.
Consider the C++ class:
</p>
<div class="code"><pre>
class Test {
string str;
public:
Test() : str("initial") {}
};
</pre></div>
<p>
and the Java proxy class generated by SWIG:
</p>
<div class="code"><pre>
public class Test {
private transient long swigCPtr;
protected transient boolean swigCMemOwn;
protected Test(long cPtr, boolean cMemoryOwn) {
swigCMemOwn = cMemoryOwn;
swigCPtr = cPtr;
}
protected static long getCPtr(Test obj) {
return (obj == null) ? 0 : obj.swigCPtr;
}
protected void finalize() {
delete();
}
// Call C++ destructor
public synchronized void delete() {
if(swigCPtr != 0 &amp;&amp; swigCMemOwn) {
swigCMemOwn = false;
exampleJNI.delete_Test(swigCPtr);
}
swigCPtr = 0;
}
// Call C++ constructor
public Test() {
this(exampleJNI.new_Test(), true);
}
}
</pre></div>
<p>
It has two methods that call JNI methods, namely, <tt>exampleJNI.new_Test()</tt> for the C++ constructor and <tt>exampleJNI.delete_Test()</tt> for the C++ destructor.
If the garbage collector collects an instance of this class, ie <tt>delete()</tt> is not explicitly called, then the C++ destructor will be run in a different thread to the main thread.
This is because when an object is marked for garbage collection, any objects with finalizers are added to a finalization queue
and the objects in the finalization queue have their <tt>finalize()</tt> methods run in a separate finalization thread.
Therefore, if the C memory allocator is not thread safe, then the heap will get corrupted sooner or later, when a concurrent C++ delete and new are executed.
It is thus essential, even in single threaded usage, to link to the C multi-thread runtime libraries,
for example, use the /MD option for Visual C++ on Windows.
Alternatively, lock all access to C++ functions that have heap allocation/deallocation.
</p>
<p>
Note that some of the STL in Visual C++ 6 is not thread safe, so although code might be linked to the multithread runtime libraries, undefined behaviour might still occur in a single threaded Java program.
Similarly some older versions of Sun Studio have bugs in the multi-threaded implementation of the std::string class and so will lead to undefined behaviour in these supposedly single threaded Java applications.
</p>
<p>
The following innocuous Java usage of Test is an example that will crash very quickly on a multiprocessor machine if the JNI compiled code is linked against the single thread C runtime libraries.
</p>
<div class="code"><pre>
for (int i=0; i&lt;100000; i++) {
System.out.println("Iteration " + i);
for (int k=0; k&lt;10; k++) {
Test test = new Test();
}
System.gc();
}
</pre></div>
<H3><a name="Java_type_wrapper_classes">27.4.4 Type wrapper classes</a></H3>
<p>
The generated type wrapper class, for say an <tt>int *</tt>, looks like this:
</p>
<div class="code"><pre>
public class SWIGTYPE_p_int {
private transient long swigCPtr;
protected SWIGTYPE_p_int(long cPtr, boolean bFutureUse) {
swigCPtr = cPtr;
}
protected SWIGTYPE_p_int() {
swigCPtr = 0;
}
protected static long getCPtr(SWIGTYPE_p_int obj) {
return obj.swigCPtr;
}
}
</pre></div>
<p>
The methods do not have public access, so by default it is impossible to do anything with objects of this class other than
pass them around. The methods in the class are part of the inner workings of SWIG.
If you need to mess around with pointers you will have to use some typemaps specific to the Java module to achieve this.
The section on <a href="#Java_typemaps">Java typemaps</a> details how to modify the generated code.
</p>
<p>
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
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
is generated for your use.
</p>
<p>
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.
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.
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.
Also recall from earlier that SWIG will use a pointer when a class is passed by value or by reference:
</p>
<div class="code">
<pre>
void spam(Snazzy *x, Snazzy &amp;y, Snazzy z);
</pre>
</div>
<p>
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.
The Java function generated is:
</p>
<div class="code">
<pre>
public static void spam(SWIGTYPE_p_Snazzy x, SWIGTYPE_p_Snazzy y, SWIGTYPE_p_Snazzy z) {
...
}
</pre>
</div>
<p>
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:
</p>
<div class="code">
<pre>
typedef int Snazzy;
void spam(Snazzy *x, Snazzy &amp;y, Snazzy z);
</pre>
</div>
<p>
Because the typedefs have been tracked the Java function generated is:
</p>
<div class="code">
<pre>
public static void spam(SWIGTYPE_p_int x, SWIGTYPE_p_int y, int z) { ... }
</pre>
</div>
<H3><a name="Java_enum_classes">27.4.5 Enum classes</a></H3>
<p>
SWIG can generate three types of enum classes.
The <a href="#Java_enumerations">Enumerations</a> section discussed these but omitted all the details.
The following sub-sections detail the various types of enum classes that can be generated.
</p>
<H4><a name="Java_typesafe_enums_classes">27.4.5.1 Typesafe enum classes</a></H4>
<p>
The following example demonstrates the typesafe enum classes which SWIG generates:
</p>
<div class="code">
<pre>
%include "enumtypesafe.swg"
%javaconst(1);
enum Beverage { ALE, LAGER=10, STOUT, PILSNER, PILZ=PILSNER };
</pre>
</div>
<p>
The following is the code that SWIG generates:
</p>
<div class="code">
<pre>
public final class Beverage {
public final static Beverage ALE = new Beverage("ALE");
public final static Beverage LAGER = new Beverage("LAGER", 10);
public final static Beverage STOUT = new Beverage("STOUT");
public final static Beverage PILSNER = new Beverage("PILSNER");
public final static Beverage PILZ = new Beverage("PILZ", PILSNER);
public final int swigValue() {
return swigValue;
}
public String toString() {
return swigName;
}
public static Beverage swigToEnum(int swigValue) {
if (swigValue &lt; swigValues.length &amp;&amp; swigValue &gt;= 0 &amp;&amp;
swigValues[swigValue].swigValue == swigValue)
return swigValues[swigValue];
for (int i = 0; i &lt; swigValues.length; i++)
if (swigValues[i].swigValue == swigValue)
return swigValues[i];
throw new IllegalArgumentException("No enum " + Beverage.class + " with value " +
swigValue);
}
private Beverage(String swigName) {
this.swigName = swigName;
this.swigValue = swigNext++;
}
private Beverage(String swigName, int swigValue) {
this.swigName = swigName;
this.swigValue = swigValue;
swigNext = swigValue+1;
}
private Beverage(String swigName, Beverage swigEnum) {
this.swigName = swigName;
this.swigValue = swigEnum.swigValue;
swigNext = this.swigValue+1;
}
private static Beverage[] swigValues = { ALE, LAGER, STOUT, PILSNER, PILZ };
private static int swigNext = 0;
private final int swigValue;
private final String swigName;
}
</pre>
</div>
<p>
As can be seen, there are a fair number of support methods for the typesafe enum pattern.
The typesafe enum pattern involves creating a fixed number of static instances of the enum class.
The constructors are private to enforce this.
Three constructors are available - two for C/C++ enums with an initializer and one for those without an initializer.
Note that the two enums with initializers, <tt>LAGER</tt> and <tt>PILZ</tt>, each call one the two different initializer constructors.
In order to use one of these typesafe enums, the <tt>swigToEnum</tt> static method must be called to return a reference to one of the static instances.
The JNI layer returns the enum value from the C/C++ world as an integer and this method is used to find the appropriate Java enum static instance.
The <tt>swigValue</tt> method is used for marshalling in the other direction.
The <tt>toString</tt> method is overridden so that the enum name is available.
</p>
<H4><a name="Java_proper_enums_classes">27.4.5.2 Proper Java enum classes</a></H4>
<p>
The following example demonstrates the Java enums approach:
</p>
<div class="code">
<pre>
%include "enums.swg"
%javaconst(1);
enum Beverage { ALE, LAGER=10, STOUT, PILSNER, PILZ=PILSNER };
</pre>
</div>
<p>
SWIG will generate the following Java enum:
</p>
<div class="code">
<pre>
public enum Beverage {
ALE,
LAGER(10),
STOUT,
PILSNER,
PILZ(PILSNER);
public final int swigValue() {
return swigValue;
}
public static Beverage swigToEnum(int swigValue) {
Beverage[] swigValues = Beverage.class.getEnumConstants();
if (swigValue &lt; swigValues.length &amp;&amp; swigValue &gt;= 0 &amp;&amp;
swigValues[swigValue].swigValue == swigValue)
return swigValues[swigValue];
for (Beverage swigEnum : swigValues)
if (swigEnum.swigValue == swigValue)
return swigEnum;
throw new IllegalArgumentException("No enum " + Beverage.class +
" with value " + swigValue);
}
private Beverage() {
this.swigValue = SwigNext.next++;
}
private Beverage(int swigValue) {
this.swigValue = swigValue;
SwigNext.next = swigValue+1;
}
private Beverage(Beverage swigEnum) {
this.swigValue = swigEnum.swigValue;
SwigNext.next = this.swigValue+1;
}
private final int swigValue;
private static class SwigNext {
private static int next = 0;
}
}
</pre>
</div>
<p>
The enum items appear first.
Like the typesafe enum pattern, the constructors are private.
The constructors are required to handle C/C++ enums with initializers.
The <tt>next</tt> variable is in the <tt>SwigNext</tt> inner class rather than in the enum class as static primitive variables cannot be modified from within enum constructors.
Marshalling between Java enums and the C/C++ enum integer value is handled via the <tt>swigToEnum</tt> and <tt>swigValue</tt> methods.
All the constructors and methods in the Java enum are required just to handle C/C++ enums with initializers.
These needn't be generated if the enum being wrapped does not have any initializers and the
<a href="#Java_simpler_enum_classes">Simpler Java enums for enums without initializers</a> section describes how typemaps can be used to achieve this.
</p>
<H4><a name="Java_typeunsafe_enums_classes">27.4.5.3 Type unsafe enum classes</a></H4>
<p>
The following example demonstrates type unsafe enums:
</p>
<div class="code">
<pre>
%include "enumtypeunsafe.swg"
%javaconst(1);
enum Beverage { ALE, LAGER=10, STOUT, PILSNER, PILZ=PILSNER };
</pre>
</div>
<p>
SWIG will generate the following simple class:
</p>
<div class="code">
<pre>
public final class Beverage {
public final static int ALE = 0;
public final static int LAGER = 10;
public final static int STOUT = LAGER + 1;
public final static int PILSNER = STOUT + 1;
public final static int PILZ = PILSNER;
}
</pre>
</div>
<H3><a name="Java_interfaces">27.4.6 Interfaces</a></H3>
<p>
By default SWIG wraps all C++ classes as Java classes.
As Java only supports derivation from a single base class, SWIG has to ignore all
bases except the first when a C++ class inherits from more than one base class.
However, there is a family of SWIG macros that change the default wrapping and allows a C++ class
to be wrapped as a Java interface instead of a Java class.