diff options
Diffstat (limited to 'Examples/java/pointer')
-rw-r--r-- | Examples/java/pointer/Makefile | 18 | ||||
-rw-r--r-- | Examples/java/pointer/example.c | 16 | ||||
-rw-r--r-- | Examples/java/pointer/example.i | 30 | ||||
-rw-r--r-- | Examples/java/pointer/index.html | 165 | ||||
-rw-r--r-- | Examples/java/pointer/runme.java | 55 |
5 files changed, 284 insertions, 0 deletions
diff --git a/Examples/java/pointer/Makefile b/Examples/java/pointer/Makefile new file mode 100644 index 0000000..968c92c --- /dev/null +++ b/Examples/java/pointer/Makefile @@ -0,0 +1,18 @@ +TOP = ../.. +SWIG = $(TOP)/../preinst-swig +SRCS = example.c +TARGET = example +INTERFACE = example.i +SWIGOPT = + +all:: java + +java:: + $(MAKE) -f $(TOP)/Makefile SRCS='$(SRCS)' SWIG='$(SWIG)' \ + SWIGOPT='$(SWIGOPT)' TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' java + javac *.java + +clean:: + $(MAKE) -f $(TOP)/Makefile java_clean + +check: all diff --git a/Examples/java/pointer/example.c b/Examples/java/pointer/example.c new file mode 100644 index 0000000..b877d9a --- /dev/null +++ b/Examples/java/pointer/example.c @@ -0,0 +1,16 @@ +/* File : example.c */ + +void add(int *x, int *y, int *result) { + *result = *x + *y; +} + +void sub(int *x, int *y, int *result) { + *result = *x - *y; +} + +int divide(int n, int d, int *r) { + int q; + q = n/d; + *r = n - q*d; + return q; +} diff --git a/Examples/java/pointer/example.i b/Examples/java/pointer/example.i new file mode 100644 index 0000000..a8ac794 --- /dev/null +++ b/Examples/java/pointer/example.i @@ -0,0 +1,30 @@ +/* File : example.i */ +%module example + +%{ +extern void add(int *, int *, int *); +extern void sub(int *, int *, int *); +extern int divide(int, int, int *); +%} + +/* This example illustrates a couple of different techniques + for manipulating C pointers */ + +/* First we'll use the pointer library */ +extern void add(int *x, int *y, int *result); +%include cpointer.i +%pointer_functions(int, intp); + +/* Next we'll use some typemaps */ + +%include typemaps.i +extern void sub(int *INPUT, int *INPUT, int *OUTPUT); + +/* Next we'll use typemaps and the %apply directive */ + +%apply int *OUTPUT { int *r }; +extern int divide(int n, int d, int *r); + + + + diff --git a/Examples/java/pointer/index.html b/Examples/java/pointer/index.html new file mode 100644 index 0000000..e20fe33 --- /dev/null +++ b/Examples/java/pointer/index.html @@ -0,0 +1,165 @@ +<html> +<head> +<title>SWIG:Examples:java:pointer</title> +</head> + +<body bgcolor="#ffffff"> + +<tt>SWIG/Examples/java/pointer/</tt> +<hr> + +<H2>Simple Pointer Handling</H2> + +<p> +This example illustrates a couple of techniques for handling +simple pointers in SWIG. The prototypical example is a C function +that operates on pointers such as this: + +<blockquote> +<pre> +void add(int *x, int *y, int *r) { + *r = *x + *y; +} +</pre> +</blockquote> + +By default, SWIG wraps this function exactly as specified and creates +an interface that expects pointer objects for arguments. +SWIG wraps a C pointer with a type wrapper class, for example, SWIGTYPE_p_int for an int*. +The only problem is how does one go about creating these objects from a Java program? +<p> + + +<h2>Possible Solutions</h2> + +<ul> +<li>Write some helper functions to explicitly create objects. For +example: + +<blockquote> +<pre> +int *new_int(int ivalue) { + int *i = (int *) malloc(sizeof(ivalue)); + *i = ivalue; + return i; +} +int get_int(int *i) { + return *i; +} + +void delete_int(int *i) { + free(i); +} +</pre> +</blockquote> + +<p> +<li>The SWIG pointer library provides an easier way. <br> +For example, in the interface file +you would do this: + +<blockquote> +<pre> +%include cpointer.i +%pointer_functions(int, intp); +</pre> +</blockquote> + +and from Java you would use pointers like this: + +<blockquote> +<pre> +SWIGTYPE_p_int a = example.new_intp(); +SWIGTYPE_p_int b = example.new_intp(); +SWIGTYPE_p_int c = example.new_intp(); +example.intp_assign(a,37); +example.intp_assign(b,42); + +// Note that getCPtr() has package access by default +System.out.println(" a =" + Long.toHexString(SWIGTYPE_p_int.getCPtr(a))); +System.out.println(" b =" + Long.toHexString(SWIGTYPE_p_int.getCPtr(b))); +System.out.println(" c =" + Long.toHexString(SWIGTYPE_p_int.getCPtr(c))); + +// Call the add() function with some pointers +example.add(a,b,c); + +// Now get the result +int res = example.intp_value(c); +System.out.println(" 37 + 42 =" + res); + +// Clean up the pointers +example.delete_intp(a); +example.delete_intp(b); +example.delete_intp(c); +</pre> +</blockquote> + +<p> +<li>Use the SWIG typemap library. This library allows you to completely +change the way arguments are processed by SWIG. For example: + +<blockquote> +<pre> +%include "typemaps.i" +void add(int *INPUT, int *INPUT, int *OUTPUT); +</pre> +</blockquote> + +And in a Java program: + +<blockquote> +<pre> +int[] r = {0}; +example.sub(37,42,r); +System.out.println("Result =" + r[0]); +</pre> +</blockquote> +Needless to say, this is substantially easier although a bit unusual. + +<p> +<li>A final alternative is to use the typemaps library in combination +with the %apply directive. This allows you to change the names of parameters +that behave as input or output parameters. For example: + +<blockquote> +<pre> +%include "typemaps.i" +%apply int *INPUT {int *x, int *y}; +%apply int *OUTPUT {int *r}; + +void add(int *x, int *y, int *r); +void sub(int *x, int *y, int *r); +void mul(int *x, int *y, int *r); +... etc ... +</pre> +</blockquote> + +</ul> + +<h2>Example</h2> + +The following example illustrates the use of these features for pointer +extraction. + +<ul> +<li> <a href="example.c">example.c</a> (C Source) +<li> <a href="example.i">example.i</a> (Swig interface) +<li> <a href="runme.java">runme.java</a> (Java program) +</ul> + +<h2>Notes</h2> + +<ul> +<li>Since pointers are used for so many different things (arrays, output values, +etc...) the complexity of pointer handling can be as complicated as you want to +make it. + +<p> +<li>More documentation on the typemaps.i and cpointer.i library files can be +found in the SWIG user manual. The files also contain documentation. + +</ul> + +<hr> +</body> +</html> diff --git a/Examples/java/pointer/runme.java b/Examples/java/pointer/runme.java new file mode 100644 index 0000000..f32f980 --- /dev/null +++ b/Examples/java/pointer/runme.java @@ -0,0 +1,55 @@ + +public class runme { + + static { + try { + System.loadLibrary("example"); + } catch (UnsatisfiedLinkError e) { + System.err.println("Native code library failed to load. See the chapter on Dynamic Linking Problems in the SWIG Java documentation for help.\n" + e); + System.exit(1); + } + } + + public static void main(String argv[]) { + + // First create some objects using the pointer library. + System.out.println("Testing the pointer library"); + SWIGTYPE_p_int a = example.new_intp(); + SWIGTYPE_p_int b = example.new_intp(); + SWIGTYPE_p_int c = example.new_intp(); + example.intp_assign(a,37); + example.intp_assign(b,42); + + // Note that getCPtr() has package access by default + System.out.println(" a =" + Long.toHexString(SWIGTYPE_p_int.getCPtr(a))); + System.out.println(" b =" + Long.toHexString(SWIGTYPE_p_int.getCPtr(b))); + System.out.println(" c =" + Long.toHexString(SWIGTYPE_p_int.getCPtr(c))); + + // Call the add() function with some pointers + example.add(a,b,c); + + // Now get the result + int res = example.intp_value(c); + System.out.println(" 37 + 42 =" + res); + + // Clean up the pointers + example.delete_intp(a); + example.delete_intp(b); + example.delete_intp(c); + + // Now try the typemap library + // Now it is no longer necessary to manufacture pointers. + // Instead we use a single element array which in Java is modifiable. + + System.out.println("Trying the typemap library"); + int[] r = {0}; + example.sub(37,42,r); + System.out.println(" 37 - 42 = " + r[0]); + + // Now try the version with return value + + System.out.println("Testing return value"); + int q = example.divide(42,37,r); + System.out.println(" 42/37 = " + q + " remainder " + r[0]); + } +} |