diff options
author | Lorry Tar Creator <lorry-tar-importer@baserock.org> | 2009-08-18 20:56:02 +0000 |
---|---|---|
committer | Lorry <lorry@roadtrain.codethink.co.uk> | 2012-09-25 16:59:08 +0000 |
commit | 9f8a09ed743cedd9547bf0661d518647966ab114 (patch) | |
tree | 9c7803d3b27a8ec22e91792ac7f7932efa128b20 /Examples/ruby/variables | |
download | swig-tarball-master.tar.gz |
Imported from /srv/lorry/lorry-area/swig-tarball/swig-1.3.40.tar.gz.HEADswig-1.3.40master
Diffstat (limited to 'Examples/ruby/variables')
-rw-r--r-- | Examples/ruby/variables/Makefile | 18 | ||||
-rw-r--r-- | Examples/ruby/variables/example.c | 91 | ||||
-rw-r--r-- | Examples/ruby/variables/example.h | 6 | ||||
-rw-r--r-- | Examples/ruby/variables/example.i | 50 | ||||
-rw-r--r-- | Examples/ruby/variables/index.html | 94 | ||||
-rw-r--r-- | Examples/ruby/variables/runme.rb | 77 |
6 files changed, 336 insertions, 0 deletions
diff --git a/Examples/ruby/variables/Makefile b/Examples/ruby/variables/Makefile new file mode 100644 index 0000000..8c4fe10 --- /dev/null +++ b/Examples/ruby/variables/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/variables/example.c b/Examples/ruby/variables/example.c new file mode 100644 index 0000000..aa4ffe9 --- /dev/null +++ b/Examples/ruby/variables/example.c @@ -0,0 +1,91 @@ +/* File : example.c */ + +/* I'm a file containing some C global variables */ + +/* Deal with Microsoft's attempt at deprecating C standard runtime functions */ +#if !defined(SWIG_NO_CRT_SECURE_NO_DEPRECATE) && defined(_MSC_VER) +# define _CRT_SECURE_NO_DEPRECATE +#endif + +#include <stdio.h> +#include <stdlib.h> +#include "example.h" + +int ivar = 0; +short svar = 0; +long lvar = 0; +unsigned int uivar = 0; +unsigned short usvar = 0; +unsigned long ulvar = 0; +signed char scvar = 0; +unsigned char ucvar = 0; +char cvar = 0; +float fvar = 0; +double dvar = 0; +char *strvar = 0; +const char cstrvar[] = "Goodbye"; +int *iptrvar = 0; +char name[256] = "Dave"; +char path[256] = "/home/beazley"; + + +/* Global variables involving a structure */ +Point *ptptr = 0; +Point pt = { 10, 20 }; + +/* A variable that we will make read-only in the interface */ +int status = 1; + +/* A debugging function to print out their values */ + +void print_vars() { + printf("ivar = %d\n", ivar); + printf("svar = %d\n", svar); + printf("lvar = %ld\n", lvar); + printf("uivar = %u\n", uivar); + printf("usvar = %u\n", usvar); + printf("ulvar = %lu\n", ulvar); + printf("scvar = %d\n", scvar); + printf("ucvar = %u\n", ucvar); + printf("fvar = %g\n", fvar); + printf("dvar = %g\n", dvar); + printf("cvar = %c\n", cvar); + printf("strvar = %s\n", strvar ? strvar : "(null)"); + printf("cstrvar = %s\n", cstrvar ? cstrvar : "(null)"); + printf("iptrvar = %p\n", iptrvar); + printf("name = %s\n", name); + printf("ptptr = %p (%d, %d)\n", ptptr, ptptr ? ptptr->x : 0, ptptr ? ptptr->y : 0); + printf("pt = (%d, %d)\n", pt.x, pt.y); + printf("status = %d\n", status); +} + +/* A function to create an integer (to test iptrvar) */ + +int *new_int(int value) { + int *ip = (int *) malloc(sizeof(int)); + *ip = value; + return ip; +} + +/* A function to create a point */ + +Point *new_Point(int x, int y) { + Point *p = (Point *) malloc(sizeof(Point)); + p->x = x; + p->y = y; + return p; +} + +char * Point_print(Point *p) { + static char buffer[256]; + if (p) { + sprintf(buffer,"(%d,%d)", p->x,p->y); + } else { + sprintf(buffer,"null"); + } + return buffer; +} + +void pt_print() { + printf("(%d, %d)\n", pt.x, pt.y); +} diff --git a/Examples/ruby/variables/example.h b/Examples/ruby/variables/example.h new file mode 100644 index 0000000..0f7e895 --- /dev/null +++ b/Examples/ruby/variables/example.h @@ -0,0 +1,6 @@ +/* File: example.h */ + +typedef struct { + int x,y; +} Point; + diff --git a/Examples/ruby/variables/example.i b/Examples/ruby/variables/example.i new file mode 100644 index 0000000..84a1509 --- /dev/null +++ b/Examples/ruby/variables/example.i @@ -0,0 +1,50 @@ +/* File : example.i */ +%module example +%{ +#include "example.h" +%} +#pragma SWIG nowarn=SWIGWARN_TYPEMAP_SWIGTYPELEAK + +/* Some global variable declarations */ +%inline %{ +extern int ivar; +extern short svar; +extern long lvar; +extern unsigned int uivar; +extern unsigned short usvar; +extern unsigned long ulvar; +extern signed char scvar; +extern unsigned char ucvar; +extern char cvar; +extern float fvar; +extern double dvar; +extern char *strvar; +extern const char cstrvar[]; +extern int *iptrvar; +extern char name[256]; + +extern Point *ptptr; +extern Point pt; +%} + + +/* Some read-only variables */ + +%immutable; + +%inline %{ +extern int status; +extern char path[256]; +%} + +%mutable; + +/* Some helper functions to make it easier to test */ +%inline %{ +extern void print_vars(); +extern int *new_int(int value); +extern Point *new_Point(int x, int y); +extern char *Point_print(Point *p); +extern void pt_print(); +%} + diff --git a/Examples/ruby/variables/index.html b/Examples/ruby/variables/index.html new file mode 100644 index 0000000..d83a87c --- /dev/null +++ b/Examples/ruby/variables/index.html @@ -0,0 +1,94 @@ +<html> +<head> +<title>SWIG:Examples:ruby:variables</title> +</head> + +<body bgcolor="#ffffff"> + +<tt>SWIG/Examples/ruby/variables/</tt> +<hr> + +<H2>Wrapping C Global Variables</H2> + +<p> +When a C global variable appears in an interface file, SWIG tries to +wrap it using a technique known as "variable linking." The idea is +pretty simple---we try to create a Ruby variable (actually module method) that +magically retrieves or updates the value of the underlying C variable when it is +accessed. Click <a href="example.i">here</a> to see a SWIG interface with some variable +declarations in it. + +<h2>Manipulating Variables from Ruby</h2> + +Before going any further, it is important to understand some important +differences between C and Ruby variables. In C, a variable is +simply a name that refers to a specific location in memory. For +example, when you declare a global variable '<tt>double a</tt>' you +know that somewhere in memory, 8 bytes have been set aside to hold a +<tt>double</tt> and that <tt>a</tt> is bound to this location for the +life of the program. In Ruby, variable creation is nothing more +than a naming operation. For example, when you say '<tt>a = 3</tt>', +'a' becomes a name that refers to some object '3'. Later on, if you say +'<tt>a = 7.5</tt>, the name 'a' is bound to an entirely different object +containing the value '7.5' (the contents of the original object are not +changed). The end result of this is that a variable in Ruby can refer +to a virtually unlimited number of different objects (memory locations) +over the lifetime of a program. + +<p> +Because of Ruby's somewhat unusual variable assignment semantics, it is not +possible to directly link a C global variable into an equivalent Ruby variable. +Instead, all C global variables are accessed as attributes of the module. +For example, if you had a global variable + +<blockquote> +<pre> +double foo; +</pre> +</blockquote> + +it will be accessed in the Ruby module as <tt>Example.foo</tt>. Click +<a href="runme.rb">here</a> to see a script that updates and prints +out the values of the variables using this technique. + +<h2>Key points</h2> + +<ul> +<li>When a global variable has the type "<tt>char *</tt>", SWIG manages it as a character +string. However, whenever the value of such a variable is set from Ruby, the old +value is destroyed using <tt>free()</tt>. +<li><tt>signed char</tt> and <tt>unsigned char</tt> are handled as small 8-bit integers. +<li>String array variables such as '<tt>char name[256]</tt>' are managed as Ruby strings, but +when setting the value, the result is truncated to the maximum length of the array. Furthermore, the string is assumed to be null-terminated. +<li>When structures and classes are used as global variables, they are mapped into pointers. +Getting the "value" returns a pointer to the global variable. Setting the value of a structure results in a memory copy from a pointer to the global. +</ul> + +<h2>Creating read-only variables</h2> + +The <tt>%immutable</tt> and <tt>%mutable</tt> directives can be used to +specify a collection of read-only variables. For example: + +<blockquote> +<pre> +%immutable; +int status; +double blah; +... +%mutable; +</pre> +</blockquote> + +The <tt>%immutable</tt> directive remains in effect until it is explicitly disabled +using the <tt>%mutable</tt> directive. + +<h2>Comments</h2> +<ul> +<li>Management of global variables is one of the most problematic aspects +of C/C++ wrapping because the scripting interface and resulting memory management +is much trickier than simply creating a wrapper function. +</ul> + +</body> +</html> +<hr> diff --git a/Examples/ruby/variables/runme.rb b/Examples/ruby/variables/runme.rb new file mode 100644 index 0000000..38531c8 --- /dev/null +++ b/Examples/ruby/variables/runme.rb @@ -0,0 +1,77 @@ +# file: runme.rb + +require 'example' + +# Try to set the values of some global variables + +Example.ivar = 42 +Example.svar = -31000 +Example.lvar = 65537 +Example.uivar = 123456 +Example.usvar = 61000 +Example.ulvar = 654321 +Example.scvar = -13 +Example.ucvar = 251 +Example.cvar = "S" +Example.fvar = 3.14159 +Example.dvar = 2.1828 +Example.strvar = "Hello World" +Example.iptrvar= Example.new_int(37) +Example.ptptr = Example.new_Point(37,42) +Example.name = "Bill" + +# Now print out the values of the variables + +puts "Variables (values printed from Ruby)" + +puts "ivar = #{Example.ivar}" +puts "svar = #{Example.svar}" +puts "lvar = #{Example.lvar}" +puts "uivar = #{Example.uivar}" +puts "usvar = #{Example.usvar}" +puts "ulvar = #{Example.ulvar}" +puts "scvar = #{Example.scvar}" +puts "ucvar = #{Example.ucvar}" +puts "fvar = #{Example.fvar}" +puts "dvar = #{Example.dvar}" +puts "cvar = #{Example.cvar}" +puts "strvar = #{Example.strvar}" +puts "cstrvar = #{Example.cstrvar}" +puts "iptrvar = #{Example.iptrvar}" +puts "name = #{Example.name}" +puts "ptptr = #{Example.ptptr} (#{Example.Point_print(Example.ptptr)})" +puts "pt = #{Example.pt} (#{Example.Point_print(Example.pt)})" + +puts "\nVariables (values printed from C)" + +Example.print_vars() + +puts "\nNow I'm going to try and modify some read only variables"; + +puts " Tring to set 'path'"; +begin + Example.path = "Whoa!" + puts "Hey, what's going on?!?! This shouldn't work" +rescue NameError + puts "Good." +end + +puts " Trying to set 'status'"; +begin + Example.status = 0 + puts "Hey, what's going on?!?! This shouldn't work" +rescue NameError + puts "Good." +end + + +puts "\nI'm going to try and update a structure variable.\n" + +Example.pt = Example.ptptr + +puts "The new value is" +Example.pt_print() +puts "You should see the value #{Example.Point_print(Example.ptptr)}" + + + |