summaryrefslogtreecommitdiff
path: root/trunk/Examples/perl5/funcptr
diff options
context:
space:
mode:
Diffstat (limited to 'trunk/Examples/perl5/funcptr')
-rw-r--r--trunk/Examples/perl5/funcptr/Makefile18
-rw-r--r--trunk/Examples/perl5/funcptr/example.c19
-rw-r--r--trunk/Examples/perl5/funcptr/example.h9
-rw-r--r--trunk/Examples/perl5/funcptr/example.i16
-rw-r--r--trunk/Examples/perl5/funcptr/index.html90
-rw-r--r--trunk/Examples/perl5/funcptr/runme.pl21
6 files changed, 173 insertions, 0 deletions
diff --git a/trunk/Examples/perl5/funcptr/Makefile b/trunk/Examples/perl5/funcptr/Makefile
new file mode 100644
index 000000000..ce2bbb5b9
--- /dev/null
+++ b/trunk/Examples/perl5/funcptr/Makefile
@@ -0,0 +1,18 @@
+TOP = ../..
+SWIG = $(TOP)/../preinst-swig
+SRCS = example.c
+TARGET = example
+INTERFACE = example.i
+SWIGOPT =
+all::
+ $(MAKE) -f $(TOP)/Makefile SRCS='$(SRCS)' SWIG='$(SWIG)' \
+ SWIGOPT='$(SWIGOPT)' TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' perl5
+
+static::
+ $(MAKE) -f $(TOP)/Makefile SRCS='$(SRCS)' SWIG='$(SWIG)' \
+ SWIGOPT='$(SWIGOPT)' TARGET='myperl' INTERFACE='$(INTERFACE)' perl5_static
+
+clean::
+ $(MAKE) -f $(TOP)/Makefile perl5_clean
+
+check: all
diff --git a/trunk/Examples/perl5/funcptr/example.c b/trunk/Examples/perl5/funcptr/example.c
new file mode 100644
index 000000000..5c4a3dabf
--- /dev/null
+++ b/trunk/Examples/perl5/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/trunk/Examples/perl5/funcptr/example.h b/trunk/Examples/perl5/funcptr/example.h
new file mode 100644
index 000000000..9936e24fc
--- /dev/null
+++ b/trunk/Examples/perl5/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/trunk/Examples/perl5/funcptr/example.i b/trunk/Examples/perl5/funcptr/example.i
new file mode 100644
index 000000000..8b3bef678
--- /dev/null
+++ b/trunk/Examples/perl5/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/trunk/Examples/perl5/funcptr/index.html b/trunk/Examples/perl5/funcptr/index.html
new file mode 100644
index 000000000..7333a39f2
--- /dev/null
+++ b/trunk/Examples/perl5/funcptr/index.html
@@ -0,0 +1,90 @@
+<html>
+<head>
+<title>SWIG:Examples:perl5:funcptr</title>
+</head>
+
+<body bgcolor="#ffffff">
+
+
+<tt>SWIG/Examples/perl5/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 script,
+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 script, you would do this:
+
+<blockquote>
+<pre>
+$r = do_op($x,$y, $ADD);
+</pre>
+</blockquote>
+
+<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.pl">runme.pl</a> (Sample script)
+</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 Perl function object in as a substitute for a C
+function pointer.
+
+<p>
+<li>A perl 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/trunk/Examples/perl5/funcptr/runme.pl b/trunk/Examples/perl5/funcptr/runme.pl
new file mode 100644
index 000000000..a73b53825
--- /dev/null
+++ b/trunk/Examples/perl5/funcptr/runme.pl
@@ -0,0 +1,21 @@
+# file: runme.pl
+
+use example;
+
+$a = 37;
+$b = 42;
+
+# Now call our C function with a bunch of callbacks
+
+print "Trying some C callback functions\n";
+print " a = $a\n";
+print " b = $b\n";
+print " ADD(a,b) = ", example::do_op($a,$b,$example::ADD),"\n";
+print " SUB(a,b) = ", example::do_op($a,$b,$example::SUB),"\n";
+print " MUL(a,b) = ", example::do_op($a,$b,$example::MUL),"\n";
+
+print "Here is what the C callback function objects look like in Perl\n";
+print " ADD = $example::ADD\n";
+print " SUB = $example::SUB\n";
+print " MUL = $example::MUL\n";
+