diff options
Diffstat (limited to 'Examples/perl5/pointer')
| -rw-r--r-- | Examples/perl5/pointer/Makefile | 18 | ||||
| -rw-r--r-- | Examples/perl5/pointer/example.c | 16 | ||||
| -rw-r--r-- | Examples/perl5/pointer/example.i | 30 | ||||
| -rw-r--r-- | Examples/perl5/pointer/index.html | 171 | ||||
| -rw-r--r-- | Examples/perl5/pointer/runme.pl | 44 |
5 files changed, 279 insertions, 0 deletions
diff --git a/Examples/perl5/pointer/Makefile b/Examples/perl5/pointer/Makefile new file mode 100644 index 0000000..ce2bbb5 --- /dev/null +++ b/Examples/perl5/pointer/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/Examples/perl5/pointer/example.c b/Examples/perl5/pointer/example.c new file mode 100644 index 0000000..8762329 --- /dev/null +++ b/Examples/perl5/pointer/example.c @@ -0,0 +1,16 @@ +/* File : example.c */ + +void add(int *x, int *y, int *result) { + *result = *x + *y; +} + +void subtract(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/perl5/pointer/example.i b/Examples/perl5/pointer/example.i new file mode 100644 index 0000000..38c67d7 --- /dev/null +++ b/Examples/perl5/pointer/example.i @@ -0,0 +1,30 @@ +/* File : example.i */ +%module example + +%{ +extern void add(int *, int *, int *); +extern void subtract(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 subtract(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/perl5/pointer/index.html b/Examples/perl5/pointer/index.html new file mode 100644 index 0000000..6f9fd39 --- /dev/null +++ b/Examples/perl5/pointer/index.html @@ -0,0 +1,171 @@ +<html> +<head> +<title>SWIG:Examples:perl5:pointer</title> +</head> + +<body bgcolor="#ffffff"> + +<tt>SWIG/Examples/perl5/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. The only +problem is how does one go about creating these objects from a script? + +<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> + +Now, in a script you would do this: + +<blockquote> +<pre> +$a = new_int(37); +$b = new_int(42); +$c = new_int(0): +add($a,$b,$c); +$r = get_int($c); +print "Result = $r\n"; +delete_int($a); +delete_int($b); +delete_int($c); +</pre> +</blockquote> + +<p> +<li>Use the SWIG pointer library. For example, in the interface file +you would do this: + +<blockquote> +<pre> +%include "pointer.i" +</pre> +</blockquote? + +and in a script you would do this: + +<blockquote> +<pre> +$a = ptrcreate("int",37); +$b = ptrcreate("int",42); +$c = ptrcreate("int"); +add($a,$b,$c); +$r = ptrvalue($c); +print "Result = $r\n"; +ptrfree($a); +ptrfree($b); +ptrfree($c); +</pre> +</blockquote> + +The advantage to using the pointer library is that it unifies some of the helper +functions behind a common set of names. For example, the same set of functions work +with int, double, float, and other fundamental types. + +<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 script: + +<blockquote> +<pre> +$r = add(37,42); +print "Result = $r\n"; +</pre> +</blockquote> +Needless to say, this is substantially easier. + +<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 subtract(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.pl">runme.pl</a> (Perl Script) +</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 pointer.i library files can be +found in the SWIG user manual. The files also contain documentation. + +<p> +<li>The pointer.i library is designed primarily for convenience. If you +are concerned about performance, you probably want to use a different +approach. + +</ul> + +<hr> +</body> +</html> diff --git a/Examples/perl5/pointer/runme.pl b/Examples/perl5/pointer/runme.pl new file mode 100644 index 0000000..4f0a89e --- /dev/null +++ b/Examples/perl5/pointer/runme.pl @@ -0,0 +1,44 @@ +# file: runme.pl + +use example; + +# First create some objects using the pointer library. +print "Testing the pointer library\n"; +$a = example::new_intp(); +$b = example::new_intp(); +$c = example::new_intp(); +example::intp_assign($a,37); +example::intp_assign($b,42); + +print " a = $a\n"; +print " b = $b\n"; +print " c = $c\n"; + +# Call the add() function with some pointers +example::add($a,$b,$c); + +# Now get the result +$r = example::intp_value($c); +print " 37 + 42 = $r\n"; + +# Clean up the pointers +example::delete_intp($a); +example::delete_intp($b); +example::delete_intp($c); + +# Now try the typemap library +# This should be much easier. Now how it is no longer +# necessary to manufacture pointers. + +print "Trying the typemap library\n"; +$r = example::subtract(37,42); +print " 37 - 42 = $r\n"; + +# Now try the version with multiple return values + +print "Testing multiple return values\n"; +($q,$r) = example::divide(42,37); +print " 42/37 = $q remainder $r\n"; + + + |
