summaryrefslogtreecommitdiff
path: root/Examples/java/funcptr
diff options
context:
space:
mode:
Diffstat (limited to 'Examples/java/funcptr')
-rw-r--r--Examples/java/funcptr/Makefile18
-rw-r--r--Examples/java/funcptr/example.c19
-rw-r--r--Examples/java/funcptr/example.h9
-rw-r--r--Examples/java/funcptr/example.i16
-rw-r--r--Examples/java/funcptr/index.html91
-rw-r--r--Examples/java/funcptr/runme.java33
6 files changed, 186 insertions, 0 deletions
diff --git a/Examples/java/funcptr/Makefile b/Examples/java/funcptr/Makefile
new file mode 100644
index 0000000..968c92c
--- /dev/null
+++ b/Examples/java/funcptr/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/funcptr/example.c b/Examples/java/funcptr/example.c
new file mode 100644
index 0000000..5c4a3da
--- /dev/null
+++ b/Examples/java/funcptr/example.c
@@ -0,0 +1,19 @@
+/* File : example.c */
+
+int do_op(int a, int b, int (*op)(int,int)) {
+ return (*op)(a,b);
+}
+
+int add(int a, int b) {
+ return a+b;
+}
+
+int sub(int a, int b) {
+ return a-b;
+}
+
+int mul(int a, int b) {
+ return a*b;
+}
+
+int (*funcvar)(int,int) = add;
diff --git a/Examples/java/funcptr/example.h b/Examples/java/funcptr/example.h
new file mode 100644
index 0000000..9936e24
--- /dev/null
+++ b/Examples/java/funcptr/example.h
@@ -0,0 +1,9 @@
+/* file: example.h */
+
+extern int do_op(int,int, int (*op)(int,int));
+extern int add(int,int);
+extern int sub(int,int);
+extern int mul(int,int);
+
+extern int (*funcvar)(int,int);
+
diff --git a/Examples/java/funcptr/example.i b/Examples/java/funcptr/example.i
new file mode 100644
index 0000000..8b3bef6
--- /dev/null
+++ b/Examples/java/funcptr/example.i
@@ -0,0 +1,16 @@
+/* File : example.i */
+%module example
+%{
+#include "example.h"
+%}
+
+/* Wrap a function taking a pointer to a function */
+extern int do_op(int a, int b, int (*op)(int, int));
+
+/* Now install a bunch of "ops" as constants */
+%constant int (*ADD)(int,int) = add;
+%constant int (*SUB)(int,int) = sub;
+%constant int (*MUL)(int,int) = mul;
+
+extern int (*funcvar)(int,int);
+
diff --git a/Examples/java/funcptr/index.html b/Examples/java/funcptr/index.html
new file mode 100644
index 0000000..56d3baa
--- /dev/null
+++ b/Examples/java/funcptr/index.html
@@ -0,0 +1,91 @@
+<html>
+<head>
+<title>SWIG:Examples:java:funcptr</title>
+</head>
+
+<body bgcolor="#ffffff">
+
+
+<tt>SWIG/Examples/java/funcptr/</tt>
+<hr>
+
+<H2>Pointers to Functions</H2>
+
+<p>
+Okay, just what in the heck does SWIG do with a declaration like this?
+
+<blockquote>
+<pre>
+int do_op(int a, int b, int (*op)(int, int));
+</pre>
+</blockquote>
+
+Well, it creates a wrapper as usual. Of course, that does raise some
+questions about the third argument (the pointer to a function).
+
+<p>
+In this case, SWIG will wrap the function pointer as it does for all other
+pointers. However, in order to actually call this function from a Java program,
+you will need to pass some kind of C function pointer object. In C,
+this is easy, you just supply a function name as an argument like this:
+
+<blockquote>
+<pre>
+/* Some callback function */
+int add(int a, int b) {
+ return a+b;
+}
+...
+int r = do_op(x,y,add);
+</pre>
+</blockquote>
+
+To make this work with SWIG, you will need to do a little extra work. Specifically,
+you need to create some function pointer objects using the %constant directive like this:
+
+<blockquote>
+<pre>
+%constant(int (*)(int,int)) ADD = add;
+</pre>
+</blockquote>
+
+Now, in a Java program, you would do this:
+
+<blockquote>
+<pre>
+int r = do_op(x,y, example.ADD)
+</pre>
+</blockquote>
+where <tt>example</tt> is the module name.
+
+<h2>An Example</h2>
+
+Here are some files that illustrate this with a simple example:
+
+<ul>
+<li><a href="example.c">example.c</a>
+<li><a href="example.h">example.h</a>
+<li><a href="example.i">example.i</a> (SWIG interface)
+<li><a href="runme.java">runme.java</a> (Sample program)
+</ul>
+
+<h2>Notes</h2>
+
+<ul>
+<li>The value of a function pointer must correspond to a function written in C or C++.
+It is not possible to pass an arbitrary Java function in as a substitute for a C
+function pointer.
+
+<p>
+<li>A Java function can be used as a C/C++ callback if you write some
+clever typemaps and are very careful about how you create your extension.
+This is an advanced topic not covered here.
+</ul>
+
+<hr>
+</body>
+</html>
+
+
+
+
diff --git a/Examples/java/funcptr/runme.java b/Examples/java/funcptr/runme.java
new file mode 100644
index 0000000..cd34c1b
--- /dev/null
+++ b/Examples/java/funcptr/runme.java
@@ -0,0 +1,33 @@
+
+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[]) {
+
+
+ int a = 37;
+ int b = 42;
+
+ // Now call our C function with a bunch of callbacks
+
+ System.out.println( "Trying some C callback functions" );
+ System.out.println( " a = " + a );
+ System.out.println( " b = " + b );
+ System.out.println( " ADD(a,b) = " + example.do_op(a,b,example.ADD) );
+ System.out.println( " SUB(a,b) = " + example.do_op(a,b,example.SUB) );
+ System.out.println( " MUL(a,b) = " + example.do_op(a,b,example.MUL) );
+
+ System.out.println( "Here is what the C callback function classes are called in Java" );
+ System.out.println( " ADD = " + example.ADD.getClass().getName() );
+ System.out.println( " SUB = " + example.SUB.getClass().getName() );
+ System.out.println( " MUL = " + example.MUL.getClass().getName() );
+ }
+}