diff options
Diffstat (limited to 'Examples/ruby/funcptr')
-rw-r--r-- | Examples/ruby/funcptr/Makefile | 18 | ||||
-rw-r--r-- | Examples/ruby/funcptr/example.c | 17 | ||||
-rw-r--r-- | Examples/ruby/funcptr/example.h | 9 | ||||
-rw-r--r-- | Examples/ruby/funcptr/example.i | 15 | ||||
-rw-r--r-- | Examples/ruby/funcptr/index.html | 90 | ||||
-rw-r--r-- | Examples/ruby/funcptr/runme.rb | 21 |
6 files changed, 170 insertions, 0 deletions
diff --git a/Examples/ruby/funcptr/Makefile b/Examples/ruby/funcptr/Makefile new file mode 100644 index 0000000..8c4fe10 --- /dev/null +++ b/Examples/ruby/funcptr/Makefile @@ -0,0 +1,18 @@ +TOP = ../.. +SWIG = $(TOP)/../preinst-swig +SRCS = example.c +TARGET = example +INTERFACE = example.i + +all:: + $(MAKE) -f $(TOP)/Makefile SRCS='$(SRCS)' SWIG='$(SWIG)' \ + TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' ruby + +static:: + $(MAKE) -f $(TOP)/Makefile SRCS='$(SRCS)' SWIG='$(SWIG)' \ + TARGET='myruby' INTERFACE='$(INTERFACE)' ruby_static + +clean:: + $(MAKE) -f $(TOP)/Makefile ruby_clean + +check: all diff --git a/Examples/ruby/funcptr/example.c b/Examples/ruby/funcptr/example.c new file mode 100644 index 0000000..99583b7 --- /dev/null +++ b/Examples/ruby/funcptr/example.c @@ -0,0 +1,17 @@ +/* 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; +} diff --git a/Examples/ruby/funcptr/example.h b/Examples/ruby/funcptr/example.h new file mode 100644 index 0000000..9936e24 --- /dev/null +++ b/Examples/ruby/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/ruby/funcptr/example.i b/Examples/ruby/funcptr/example.i new file mode 100644 index 0000000..39390da --- /dev/null +++ b/Examples/ruby/funcptr/example.i @@ -0,0 +1,15 @@ +/* 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; + + diff --git a/Examples/ruby/funcptr/index.html b/Examples/ruby/funcptr/index.html new file mode 100644 index 0000000..980106c --- /dev/null +++ b/Examples/ruby/funcptr/index.html @@ -0,0 +1,90 @@ +<html> +<head> +<title>SWIG:Examples:ruby:funcptr</title> +</head> + +<body bgcolor="#ffffff"> + + +<tt>SWIG/Examples/ruby/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.rb">runme.rb</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 Ruby proc object in as a substitute for a C +function pointer. + +<p> +<li>A ruby proc 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/ruby/funcptr/runme.rb b/Examples/ruby/funcptr/runme.rb new file mode 100644 index 0000000..4a5b014 --- /dev/null +++ b/Examples/ruby/funcptr/runme.rb @@ -0,0 +1,21 @@ +# file: runme.rb + +require '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 Ruby\n" +print " ADD = #{Example::ADD}\n" +print " SUB = #{Example::SUB}\n" +print " MUL = #{Example::MUL}\n" + |