This chapter describes SWIG’s support for wrapping C++. As a prerequisite, you should first read the chapter SWIG-3: Wrap ANSI C Type to see how SWIG wraps ANSI C. Support for C++ builds upon ANSI C wrapping and that material will be useful in understanding this chapter.
SWIG only provides support for a subset of C++ features. Fortunately, this is now a rather large subset. there is no semantically obvious (or automatic ) way to map many of its advanced features into other languages. As a simple example:
In contrast, C++ has increasingly relied upon generic programming and templates for much of its functionality. Although templates are a powerful feature, they are largely orthogonal to the whole notion of binary components and libraries. For example, an STL vector does not define any kind of binary object for which SWIG can just create a wrapper.
To wrap C++, SWIG uses a layered approach to code generation.
At the lowest level, SWIG generates a collection of procedural ANSI-C style wrappers. These wrappers take care of basic type conversion, type checking, error handling, and other low-level details of the C++ binding.
These wrappers are also sufficient to bind C++ into any target language that supports built-in procedures. In some sense, you might view this layer of wrapping as providing a C library interface to C++.
On top of the low-level procedural (flattened) interface, SWIG generates proxy classes that provide a natural object-oriented (OO) interface to the underlying code. The proxy classes are typically written in the target language itself. For instance, in Python, a real Python class is used to provide a wrapper around the underlying C++ object.
SWIG tries to maintain a very strict and clean separation between the implementation of your C++ application and the resulting wrapper code.it does not play sneaky tricks with the C++ type system, it doesn’t mess with your class hierarchies, and it doesn’t introduce new semantics.
NOTE: Although this approach might not provide the most seamless integration with C++ (not most efficiently), it is safe, simple, portable, and debuggable.
Some of this chapter focuses on the low-level procedural interface to C++ that is used as the foundation for all language modules.
NOTE: Keep in mind that the target languages also provide the high-level OO interface via proxy classes. More detailed coverage can be found in the documentation for each target language.
SWIG currently supports most C++ features including the following:
The following C++ features are not currently supported:
NOTE: As a rule of thumb, SWIG should not be used on raw C++ source files, use header files only.
When wrapping C++ code, it is critical that SWIG be called with the -c++
option.
When compiling and linking the resulting wrapper file, it is normal to use the C++
compiler. For example:
$ swig -c++ -tcl example.i
$ c++ -fPIC -c example_wrap.cxx
$ c++ example_wrap.o $(OBJS) -o example.so
Unfortunately, the process varies slightly on each platform. Make sure you refer to the documentation on each target language for further details.
if you’re building a Python module, each C++ class is wrapped by a Python proxy class.
Or if you’re building a Java module, each C++ class is wrapped by a Java proxy class.
roxy classes are always constructed as an extra layer of wrapping that uses low-level accessor functions. To illustrate, suppose you had a C++ class like this:
class Foo {
public:
Foo();
~Foo();
int bar(int x);
int x;
};
the real proxy class is written in the target language. For example, in Python, the proxy might look roughly like this:
class Foo:
def __init__(self):
self.this = new_Foo()
def __del__(self):
delete_Foo(self.this)
def bar(self, x):
return Foo_bar(self.this, x)
def __getattr__(self, name):
if name == 'x':
return Foo_x_get(self.this)
# ...
def __setattr__(self, name, value):
if name == 'x':
Foo_x_set(self.this, value)
# ...
NOTE: the low-level accessor functions are always used by the proxy classes. Whenever possible, proxies try to take advantage of language features that are similar to C++. This might include operator overloading, exception handling, and other features.
A major issue with proxies concerns the memory management of wrapped objects. Consider the following C++ code:
class Foo
{
public:
Foo();
~Foo();
int bar(int x);
int x;
};
class Spam
{
public:
Foo *value;
...
};
Consider some script code that uses these classes:
f = Foo() # Creates a new Foo 1
s = Spam() # Creates a new Spam 1
s.value = f # Stores a reference to f inside s 2
g = s.value # Returns stored reference 3
g = 4 # Reassign g to some other value 4
del f # Destroy f 5
1.When objects are created in the script, the objects are wrapped by newly
created proxy classes. That is, there is both a new proxy class instance and
a new instance of the underlying C++ class.In this example, both f
and s
are created in this way.
2.However, the statement s.value is rather curious. s.value
is a script
representations of Foo*
. when executed, a pointer to f is set to Foo* value inside
the underlying C++ object of s
. This means that the scripting proxy class
AND another C++ class share a reference to the same object. As a result,
now the underlying C++ object of s
stores a reference to the underlying
C++ object of f
.
3.To make matters even more interesting, consider the statement g = s.value
.
When executed, this creates a new proxy class g that provides a wrapper
around the C++ object stored in s.value
.
In general, there is no way to know where this object came from—it could have been created by the script, but it could also have been generated internally.
In this particular example, the assignment of g results in a second proxy
class for Foo
. In other words, a reference to Foo
is now shared by two proxy
objects (f
and g
) and a C++ object(Spam
).
4.In the statement, g=4, the variable g is reassigned. In many languages, this makes the old value of g available for garbage collection. Therefore, this causes one of the proxy classes to be destroyed.
5.Later on, the statement del f destroys the other proxy class.
Of course, there is still a reference to the original object stored inside another C++ object. What happens to it? Is the object still valid?
To answer this problem, we must talk anout proxy classes that provide an API for controlling ownership. In C++ pseudocode, ownership control might look roughly like this:
class FooProxy {
public:
Foo *self;
int thisown;
FooProxy() {
self = new_Foo();
thisown = 1; // Newly created object
}
~FooProxy() {
if (thisown) delete_Foo(self);
}
...
// Ownership control API
void disown() {
thisown = 0;
}
void acquire() {
thisown = 1;
}
};
class FooPtrProxy: public FooProxy {
public:
FooPtrProxy(Foo *s) {
self = s;
thisown = 0;
}
};
class SpamProxy {
...
FooProxy *value_get() {
return FooPtrProxy(Spam_value_get(self));
}
void value_set(FooProxy *v) {
Spam_value_set(self, v->self);
v->disown();
}
...
};
Looking at this code, there are a few central features:
Given the tricky nature of C++ memory management, it is impossible for proxy classes to automatically handle every possible memory management problem. However, proxies do provide a mechanism for manual control that can be used (if necessary) to address some of the more tricky memory management problems.
NOTE: Language specific details on proxy classes are contained in the chapters describing each target language. This chapter has merely introduced the topic in a very general way.
The following code shows a SWIG interface file for a simple C++ class:
%module list
%{
#include "list.h"
%}
// Very simple C++ example for linked list
class List
{
public:
List();
~List();
int search(char *value);
void insert(char *);
void remove(char *);
char *get(int n);
static void print(List *l);
int length;
};
To generate wrappers for this class, SWIG first reduces the class to a collection of low-level C-style accessor functions which are then used by the proxy classes.
C++ constructors and destructors are translated into accessor functions such as the following :
List * new_List(void) {
return new List;
}
void delete_List(List *l) {
delete l;
}
Following the C++ rules for implicit constructor and destructors, SWIG will automatically assume there is one even when they are not explicitly declared in the class interface.
In general then:
%copyctor
is used.And as in C++, a few rules that alters the previous behavior:
To manually disable these, the %nodefaultctor
and %nodefaultdtor
feature
flag directives can be used.
NOTE: that these directives only affects the Implicit generation, and they have no effect if the default/copy constructors or destructor are explicitly declared in the class interface.
For example:
%nodefaultctor Foo; // Disable the default constructor for class Foo.
class Foo {
// No default constructor is generated, unless one is declared
...
};
class Bar {
// A default constructor is generated, if possible
...
};
The directive %nodefaultctor
can also be applied “globally”, as in:
%nodefaultctor; // Disable creation of default constructors
class Foo {
// No default constructor is generated, unless one is declared
...
};
class Bar {
public:
Bar();
// The default constructor is generated, since one is declared
};
%clearnodefaultctor; // Enable the creation of default constructors again
The corresponding %nodefaultdtor
directive can be used to disable the
generation of the default or implicit destructor:
%nodefaultdtor Foo; // Disable the implicit/default destructor for class Foo.
class Foo {
// No destructor is generated, unless one is declared
...
};
Note: The %nodefault
directive/ -nodefault
options described above,
which disable both the default constructor and the implicit destructors,
could lead to memory leaks, and so it is strongly recommended to not use them.
If a class defines a constructor, SWIG normally tries to generate a wrapper for it. However, SWIG will not generate a constructor wrapper if it thinks that it will result in illegal wrapper code. There are really two cases where this might show up.
First, SWIG won’t generate wrappers for protected or private constructors. For example:
class Foo {
protected:
Foo(); // Not wrapped.
public:
...
};
Next, SWIG won’t generate wrappers for a class if it appears to be abstract–that is, it has undefined pure virtual methods. Here are some examples:
class Bar {
public:
Bar(); // Not wrapped. Bar is abstract.
virtual void spam(void) = 0;
};
class Grok : public Bar {
public:
Grok(); // Not wrapped. No implementation of abstract spam().
// but You can use `%feature("notabstract") Foo;` to force wrapping `Grok();`
};
If a class defines more than one constructor, its behavior depends on the capabilities of the target language. If overloading is supported, the copy constructor is accessible using the normal constructor function. For example, if you have this:
class List {
public:
List();
List(const List &); // Copy constructor
...
};
then the copy constructor can be used in script as follows:
x = List() # Create a list
y = List(x) # Copy list x
If the target language does not support overloading, then the copy constructor is available through a special function like this:
List *copy_List(List *f) {
return new List(*f);
}
then the copy constructor can be used in script as follows:
x = List() # Create a list
y = copy_List(x) # Copy list x
Note: SWIG does not generate a copy constructor wrapper unless one
is explicitly declared in the class. This differs from the treatment of default
constructors and destructors. However, copy constructor wrappers can
be generated if using the copyctor
feature flag. For example:
%copyctor List;
class List {
public:
List();
};
Will generate a copy constructor wrapper for List.
All member functions are roughly translated into accessor functions like this :
int List_search(List *obj, char *value) {
return obj->search(value);
}
It should be noted that SWIG does not actually create a C accessor
function in the code it generates. Instead, member access such as
obj->search(value)
is directly inlined into the generated wrapper functions.
Static member functions are called directly without making any special transformations. For example, the static member function print(List *l) directly invokes List::print(List *l) in the generated wrapper code.
SWIG will wrap all types of functions that have default arguments. For example member functions:
class Foo {
public:
void bar(int x, int y = 3, int z = 4);
};
SWIG handles default arguments by generating an extra overloaded method for each defaulted argument.
class Foo {
public:
void bar(int x, int y, int z);
void bar(int x, int y);
void bar(int x);
};
class Swig {
public:
enum {ALE, LAGER, PORTER, STOUT};
};
Generates the following set of constants in the target scripting language :
Swig_ALE = Swig::ALE
Swig_LAGER = Swig::LAGER
Swig_PORTER = Swig::PORTER
Swig_STOUT = Swig::STOUT
C++ references are supported, but SWIG transforms them back into pointers. For example, a declaration like this :
class Foo {
public:
double bar(double &a);
}
has a low-level accessor:
double Foo_bar(Foo *obj, double *a) {
obj->bar(*a);
}
As a special case, most language modules pass const references to primitive data types (int, short, float, etc.) by value instead of pointers. For example, if you have a function like this,
void foo(const int &x);
it is called from a script as follows: foo(3) # Notice pass by value
Functions that return a reference are remapped to return a pointer instead. For example:
class Bar {
public:
Foo &spam();
};
Generates an accessor like this:
Foo *Bar_spam(Bar *obj) {
Foo &result = obj->spam();
return &result;
}
However, functions that return const references to primitive
data types (int, short, etc.) normally return the result as a value
rather than a pointer. For example, a function like this, const int &bar();
will will return integers such as 37 or 42 in the target scripting language
rather than a pointer to an integer.
C *c = new C();
void *p = (void *) c;
void *pA = (void *) c;
void *pB = (void *) c;
...
int x = A_function((A *) pA);
int y = B_function((B *) pB);
In practice, the pointer is held as an integral number in the target language proxy class.
For example, a class with a member template might look like this:
class Foo {
public:
template<class T> void bar(T x, T y) { ... };
...
};
if you want to leave the original class definition alone, just do this:
class Foo {
public:
template<class T> void bar(T x, T y) { ... };
...
};
...
%template(bari) Foo::bar<int>;
%template(bard) Foo::bar<double>;
This blog provides a brief overview of:
C/C++ can be used for maximal performance and complicated systems programming tasks.
Scripting languages can be used for rapid prototyping, interactive debugging, scripting,
and access to high-level data structures such associative arrays.
By extending the interpreter, it is usually possible to add new commands and variables.
To do this, most lang define a special API for adding new commands. Furthermore, a special foreign function interface defines how these new commands are supposed to hook into the interpreter.
Typically, when you add a new command to a scripting interpreter you need to do two things:
Suppose you have an ordinary C function like this :
int fact(int n) {
if (n <= 1) return 1;
else return n*fact(n-1);
}
A wrapper function for it must do three things :
As an example, the Tcl wrapper function for the fact() function above example might look like the following :
int wrap_fact(ClientData clientData,
Tcl_Interp *interp,
int argc,
char *argv[])
{
int result;
int arg0;
if (argc != 2)
{
interp->result = "wrong # args";
return TCL_ERROR;
}
arg0 = atoi(argv[1]);
result = fact(arg0);
sprintf(interp->result,"%d", result);
return TCL_OK;
}
Once you have created a wrapper function, the final step is to tell the scripting language about the new function. This is usually done in an initialization function called by the language when the module is loaded.
For example, adding the above function to the Tcl interpreter requires code like the following :
int Wrap_Init(Tcl_Interp *interp)
{
Tcl_CreateCommand(interp,
"fact", wrap_fact,
(ClientData) NULL,
(Tcl_CmdDeleteProc *) NULL);
return TCL_OK;
}
When executed, Tcl will now have a new command called “fact” that you can use like any other Tcl command.
Although the process of adding a new function to Tcl has been illustrated, the procedure is almost identical for Perl and Python. Both require special wrappers to be written and both need additional initialization code. Only the specific details are different.
ariable linking refers to the problem of mapping a C/C++ global variable to a variable in the scripting language
interpreter. For example, suppose you had the following variable: double Foo = 3.5;
evaluating a variable such as $Foo might implicitly call the get function. Similarly, typing $Foo = 4 would call the underlying set function to change the value.
In many cases, a C program or library may define a large collection of constants. For example:
#define RED
0xff0000
#define BLUE 0x0000ff
#define GREEN 0x00ff00
To make constants available, their values can be stored in scripting language variables such as $RED, $BLUE, and $GREEN. Virtually all scripting languages provide C functions for creating variables so installing constants is usually a trivial exercise.
The most straightforward technique for handling structures is to implement a collection of accessor functions that hide the underlying representation of a structure. For example:
struct Vector {
Vector();
~Vector();
double x, y, z;
};
can be transformed into the following set of functions :
Vector *new_Vector();
void delete_Vector(Vector *v);
double Vector_x_get(Vector *v);
double Vector_y_get(Vector *v);
double Vector_z_get(Vector *v);
void Vector_x_set(Vector *v, double x);
void Vector_y_set(Vector *v, double y);
void Vector_z_set(Vector *v, double z);
Now, from an interpreter these function might be used as follows:
% set v [new_Vector]
% Vector_x_set $v 3.5
% Vector_y_get $v
% delete_Vector $v
% ...
Since accessor functions provide a mechanism for accessing the internals of an object, the interpreter does not need to know anything about the actual representation of a Vector.
In certain cases, it is possible to use the low-level accessor functions to create a proxy class, also known as a shadow class. For example, if you have the following C++ definition :
class Vector
{
public:
Vector();
~Vector();
double x, y, z;
};
proxy classing mechanism would allow you to access the structure in a more natural manner from the interpreter. For example, in Python, you might want to do this:
>>> v = Vector()
>>> v.x = 3
>>> v.y = 4
>>> v.z = -13
>>> ...
>>> del v
In the following blogs, we will go to the details of proxy class. See you then!
For example, consider the following interface file:
%module example
%inline %{
extern double sin(double x);
extern int strcmp(const char *, const char *);
extern int Foo;
%}
#define STATUS 50
#define VERSION "1.1"
When SWIG creates an extension module, these declarations are accessible as scripting language functions, variables, and constants respectively. For example, in python:
>>> example.sin(3)
5.2335956
>>> example.strcmp('Dave', 'Mike')
-1
>>> print example.cvar.Foo
42
>>> print example.STATUS
50
>>> print example.VERSION
1.1
Whenever possible, SWIG creates an interface that closely matches the underlying C/C++ code. However, due to subtle differences between languages, run-time environments, and semantics, it is not always possible to do so.
In order to build an interface, SWIG has to convert C/C++ datatypes to equivalent types in the target language:
When an integral value is converted from C, a cast is used to convert it to the representation in the target language. Thus, a 16 bit short in C may be promoted to a 32 bit integer. When integers are converted in the other direction, the value is cast back into the original C type. If the value is too large to fit, it is silently truncated.
bool data type is cast to and from an integer value of 0 and 1 unless the target language provides a special boolean type.
unsigned/signed char are special cases that are handled as small 8-bit integers. Normally, the char datatype is mapped as a one-character ASCII string.
As a rule of thumb, the int datatype and all variations of char and short datatypes are safe to use. For unsigned int and long data types, you will need to carefully check the correct operation of your program after it has been wrapped with SWIG.
SWIG recognizes the following floating point types : float and double. Floating point numbers are mapped to and from the natural representation of floats in the target language. This is almost always a C double.
For those scripting languages that provide Unicode support, Unicode strings are often available in an 8-bit representation such as UTF-8 that can be mapped to the char * type (in which case the SWIG interface will probably work).
Whenever possible, SWIG maps C/C++ global variables into scripting language variables.
Whenever the scripting language variable is used, the underlying C global variable is accessed。 However, the way to access global variables in different script langs are different.
Finally, if a global variable has been declared as const, it only supports read-only access.
For example:
%module example
double foo;
results in a scripting language variable like this:
# Tcl
set foo [3.5] ;# Set foo to 3.5
puts $foo ;# Print the value of foo
# Python
cvar.foo = 3.5 # Set foo to 3.5
print cvar.foo # Print value of foo
# Perl
$foo = 3.5; # Set foo to 3.5
print $foo, "\n"; # Print value of foo
# Ruby
Module.foo = 3.5 # Set foo to 3.5
print Module.foo, "\n" # Print value of foo
Constants can be created using #define, enumerations, or a special %constant directive. The following interface file shows a few valid constant declarations :
#define I_CONST 5 // An integer constant
#define PI 3.14159 // A Floating point constant
#define S_CONST "hello world" // A string constant
#define NEWLINE '\n' // Character constant
enum boolean {NO=0, YES=1};
enum months {JAN, FEB, MAR, APR, MAY, JUN, JUL, AUG,
SEP, OCT, NOV, DEC};
%constant double BLAH = 42.37;
#define PI_4 PI/4
#define FLAGS 0x04 | 0x08 | 0x40
1.SWIG will not create constants for macros unless the value can be completely determined by the preprocessor.
#define EXTERN extern
EXTERN void foo();
what would the value of a constant called EXTERN would be?
2.for the same conservative reasons even a constant with a simple cast will be ignored, such as
#define F_CONST (double) 5 // A floating point constant with cast
3.For enumerations, it is critical that the original enum definition be included somewhere in the interface file (either in a header file or in the %{ %} block) because it needs the original enumeration declaration in order to get the correct enum values as assigned by the C compiler.
Typically, %constant is only used when you want to add constants to the scripting language interface that are not defined in the original header file.
If the right-most const occurs after all other type modifiers (such as pointers), then the variable is const. Otherwise, it is not. Here are some examples of const declarations:
const char a; // A constant character
char const b; // A constant character (the same)
char *const c; // A constant pointer to a character
const char *const d; // A constant pointer to a constant character
Here is an example of a declaration that is not const:
const char *e;
In this case, the pointer e can change — it’s only the value being pointed to that is read-only.
When strings are passed from a scripting language to a C char *, the pointer usually points to string data stored inside the interpreter.
char *strcat(char *s, const char *t)
your application will perhaps crashes with a segmentation fault or other memory related problem. This is because s refers to some internal data in the target language—data that you should mot be touching.
Pointers to primitive C data types such as:
int* p_int;
double*** ppp_double;
char** pp_char;
Int* null_ptr=NULL;
are fully supported by SWIG.
Rather than trying to convert the data being pointed to into a scripting representation, SWIG simply encodes the pointer itself into a representation that contains the actual value of the pointer and a type-tag.
Thus, the SWIG representation of the above pointers (in Tcl), might look like this:
_10081012_p_int
_1008e124_ppp_double
_f8ac_pp_char
_NULL_p_int
All pointers are treated as opaque objects by SWIG. Thus, a pointer may be returned by a function and passed around to other C functions as needed. (? here is something I feel unclear and need go over in the future.)
The scripting language representation of a pointer value should never be manipulated directly.
eg. the numbers used may differ from the actual machine address (e.g., on little-endian machines,
the digits may appear in reverse order)
Although this has the potential to cause a crash, NULL pointers are also
sometimes used as sentinel values or to denote a missing/empty value.
Therefore, SWIG leaves NULL pointer checking up to the application.
(? here is something I feel unclear when I wrote this blog and need go
over in the future.)
For everything else (structs, classes, arrays, etc…) SWIG applies a very simple rule :
Everything else is a pointer
Suppose you have an interface file like this :
%module fileio
FILE *fopen(char *, char *);
int fclose(FILE *);
unsigned fread(void *ptr, unsigned size, unsigned nobj, FILE *);
unsigned fwrite(void *ptr, unsigned size, unsigned nobj, FILE *);
void *malloc(int nbytes);
void free(void *);
In this file, SWIG doesn’t know what a FILE is, but since it’s used as a pointer, so it doesn’t really matter what it is. If you wrapped this module into Python, you can use the functions just like you expect :
# Copy a file
def filecopy(source, target):
f1 = fopen(source, "r")
f2 = fopen(target, "w")
buffer = malloc(8192)
nbytes = fread(buffer, 8192, 1, f1)
while (nbytes > 0):
fwrite(buffer, 8192, 1, f2)
nbytes = fread(buffer, 8192, 1, f1)
free(buffer)
In this case f1, f2, and buffer are all opaque objects containing C pointers. It doesn’t matter what value they contain–our program works just fine without this knowledge.
When SWIG encounters an undeclared data type, it automatically assumes that it is a structure or class.
Like C, typedef can be used to define new type names in SWIG. For example:
typedef unsigned int size_t;
typedef definitions appearing in a SWIG interface are not propagated to the generated wrapper code.
Therefore, they either need to be defined in an included header file or placed in the declarations section like this:
%{
/* Include in the generated wrapper file */
typedef unsigned int size_t;
%}
/* Tell SWIG about it */
typedef unsigned int size_t;
or
%inline %{ typedef unsigned int size_t; %}
SWIG tracks typedef declarations and uses this information for run-time type checking.
For instance, if you use the above typedef and had the following function declaration:
void foo(unsigned int *ptr);
The corresponding wrapper function will accept arguments of type unsigned int * or size_t *.
For example, consider the following function:
double dot_product(Vector a, Vector b);
To deal with this, SWIG transforms the function to use pointers by creating a wrapper equivalent to the following:
double wrap_dot_product(Vector *a, Vector *b)
{
Vector x = *a;
Vector y = *b;
return dot_product(x, y);
}
In the target language, the dot_product() function now accepts pointers to Vectors instead of Vectors. For the most part, this transformation is transparent so you might not notice.
For example, consider the following function:
Vector cross_product(Vector v1, Vector v2);
This function wants to return Vector, but SWIG only really supports pointers. As a result, SWIG creates a wrapper like this:
Vector *wrap_cross_product(Vector *v1, Vector *v2)
{
Vector x = *v1;
Vector y = *v2;
Vector *result;
result = (Vector *) malloc(sizeof(Vector));
*(result) = cross(x, y);
return result;
}
Or if SWIG was run with the -c++ option:
Vector *wrap_cross(Vector *v1, Vector *v2)
{
Vector x = *v1;
Vector y = *v2;
Vector *result = new Vector(cross(x, y)); // Uses default copy constructor
return result;
}
In both cases, SWIG allocates a new object and returns a reference to it. It is up to the user to delete the returned object when it is no longer in use.
Clearly, this will leak memory if you are unaware of the implicit memory allocation and don’t take steps to free the result.
It should also be noted that the handling of pass/return by value in C++ has some special cases.
For example, the above code fragments don’t work correctly if Vector doesn’t define a default constructor. The section on SWIG and C++ has more information about this case.
For example, a global variable like this:
Vector unit_i;
gets mapped to an underlying pair of set/get functions like this :
Vector *unit_i_get()
{
return &unit_i;
}
void unit_i_set(Vector *value)
{
unit_i = *value;
}
A global variable created in this manner will show up as a pointer in the target scripting language. It would be an extremely bad idea to free or destroy such a pointer.
Also, C++ classes must supply a properly defined copy constructor in order for assignment to work correctly.
When a global variable of type char * appears, SWIG uses malloc() or new to allocate memory for the new value.
Specifically, if you have a variable like this
char *foo;
SWIG generates the following code:
/* C mode */
void foo_set(char *value)
{
if (foo) free(foo);
foo = (char *) malloc(strlen(value)+1);
strcpy(foo, value);
}
/* C++ mode. When -c++ option is used */
void foo_set(char *value)
{
if (foo) delete [] foo;
foo = new char[strlen(value)+1];
strcpy(foo, value);
}
If this is not the behavior that you want, consider making the variable read-only using the %immutable directive.
Alternatively, you might write a short assist-function to set the value exactly like you want. For example:
%inline %{
void set_foo(char *value)
{
strncpy(foo, value, 50);
}
%}
Note: If you write an assist function like this, you will have to call it as a function from the target scripting language (it does not work like a variable). For example, in Python you will have to write:
>>> set_foo("Hello World")
A common mistake with char * variables is to link to a variable declared like this:
char *VERSION = "1.0";
In this case, the variable will be readable, but any attempt to change the value results in a segmentation or general protection fault.
This is due to the fact that SWIG is trying to release the old value using free or delete when the string literal value currently assigned to the variable wasn’t allocated using malloc() or new.
To fix this behavior, you can either:
char VERSION[32] = "1.0";
SWIG still generates functions for setting and getting the value. However, the default behavior does not release the previous contents (resulting in a possible memory leak).
In fact, you may get a warning message such as this when wrapping such a variable:
example.i:20. Typemap warning. Setting const char * variable may leak memory
The reason for this behavior is that const char * variables are often used to point to string literals. For example:
const char *foo = "Hello World\n";
On the other hand, it is legal to change the pointer to point to some other value.
When setting a variable of this type, SWIG allocates a new string (using malloc or new) and changes the pointer to point to the new value.
However, the following repeated modifications of the value will result in a memory leak since the old value is not released by default.
Anyway, try to use const char* or char* as read-only.
Arrays are fully supported by SWIG, but they are always handled as pointers instead of mapping them to a special array object or list in the target language.
Thus, the following declarations :
int foobar(int a[40]);
void grok(char *argv[]);
void transpose(double a[20][20]);
are processed as if they were really declared like this:
int foobar(int *a);
void grok(char **argv);
void transpose(double (*a)[20]);
Like C, SWIG does not perform array bounds checking. It is up to the user to make sure the pointer points to a suitably allocated region of memory.
Multi-dimensional arrays are transformed into a pointer to an array of one less dimension. For example:
int [10]; // Maps to int *
int [10][20]; // Maps to int (*)[20]
int [10][20][30]; // Maps to int (*)[20][30]
Array variables are supported, but are read-only by default. For example:
int a[100][200];
In this case, reading the variable ‘a’ returns a pointer of type int (*)[200]
that points to the first element of the array &a[0][0]
.
Trying to modify ‘a’ results in an error. This is because SWIG does not know how to copy data from the target language into the array.
To work around this limitation, you may want to write a few simple assist functions like this: For example:
%inline %{
void a_set(int i, int j, int val)
{
a[i][j] = val;
}
int a_get(int i, int j)
{
return a[i][j];
}
%}
In the target language, the value cannot be set/get like a normal variable but set/get it like this:
a_set(0,0,1) # set a[0][0] to 1
val = a_get(0,0) # get a[0][0]
To dynamically create arrays of various sizes and shapes, it may be useful to write some helper functions in your interface. For example:
// Some array helpers
%inline %{
/* Create any sort of [size] array */
int *int_array(int size)
{
return (int *) malloc(size*sizeof(int));
}
/* Create a two-dimension array [size][10] */
int (*int_array_10(int size))[10]
{
return (int (*)[10]) malloc(size*10*sizeof(int));
}
%}
Arrays of char are handled as a special case by SWIG. In this case, strings in the target language can be stored in the array.
For example, if you have a declaration like this,
char pathname[256];
SWIG generates functions for both getting and setting the value that are equivalent to the following code:
char *pathname_get()
{
return pathname;
}
void pathname_set(char *value)
{
strncpy(pathname, value, 256);
}
The difference is that in the target language, the value can be set/get like a normal variable.
pathname = 'python' # set
print pathname # get
For example:
int plot(double x, double y, int color=WHITE);
SWIG generates wrapper code where the default arguments are optional in the target language:
plot -3.4 7.5 # Use default value
plot -3.4 7.5 10 # set color to 10 instead
SWIG provides full support for function pointers provided that the callback functions are defined in C and not in the target language.
For example, consider a function like this:
int binary_op(int a, int b, int (*op)(int, int));
When you first wrap something like this into an extension module, you may find the function to be impossible to use. For instance, in Python:
>>> def add(x, y):
... return x+y
...
>>> binary_op(3, 4, add)
Traceback (most recent call last):
File "<stdin>", line 1, in ?
TypeError: Type error. Expected _p_f_int_int__int
>>>
The reason for this error is that SWIG doesn’t know how to map a scripting language function into a C callback.
However, existing C functions can be used as arguments provided you install them as constants. One way to do this is to use the %constant directive like this:
/* Function with a callback */
int binary_op(int a, int b, int (*op)(int, int));
/* Some callback functions */
%constant int add(int, int);
%constant int sub(int, int);
%constant int mul(int, int);
In this case, add, sub, and mul become function pointer constants in the target scripting language. This allows you to use them as follows:
>>> binary_op(3, 4, add)
7
>>> binary_op(3, 4, mul)
12
>>>
Unfortunately, by declaring the callback functions as constants, they are no longer accessible as functions. For example:
>>> add(3, 4)
Traceback (most recent call last):
File "<stdin>", line 1, in ?
TypeError: object is not callable: '_ff020efc_p_f_int_int__int'
>>>
If you want to make a function available as both a callback function and a function, you can use the %callback and %nocallback directives like this:
/* Function with a callback */
int binary_op(int a, int b, int (*op)(int, int));
/* Some callback functions */
%callback("%s_cb");
int add(int, int);
int sub(int, int);
int mul(int, int);
%nocallback;
%s
gets replaced by the function name. The callback mode remains in
effect until it is explicitly disabled using %nocallback
. When you do this,
the interface now works as follows:
>>> binary_op(3, 4, add_cb)
7
>>> binary_op(3, 4, mul_cb)
12
>>> add(3, 4)
7
>>> mul(3, 4)
12
Notice that when the function is used as a callback, special names
such as add_cb
are used instead. To call the function normally,
just use the original function name such as add()
.
Although SWIG does not normally allow callback functions to be written in the target language, this can be accomplished with the use of type maps and other advanced SWIG features.
See the Typemaps chapter for more about typemaps and individual target language chapters for more on callbacks and the ‘director’ feature.
If SWIG encounters the definition of a C structure or union, it creates a set of accessor functions. For example:
struct Vector
{
double x, y, z;
}
gets transformed into the following set of accessor functions :
double Vector_x_get(struct Vector *obj)
{
return obj->x;
}
double Vector_y_get(struct Vector *obj)
{
return obj->y;
}
double Vector_z_get(struct Vector *obj)
{
return obj->z;
}
void Vector_x_set(struct Vector *obj, double value)
{
obj->x = value;
}
void Vector_y_set(struct Vector *obj, double value)
{
obj->y = value;
}
void Vector_z_set(struct Vector *obj, double value)
{
obj->z = value;
}
In addition, SWIG creates default constructor and destructor functions if none are defined in the interface. For example:
struct Vector *new_Vector()
{
return (Vector *) calloc(1, sizeof(struct Vector));
}
void delete_Vector(struct Vector *obj)
{
free(obj);
}
Using these low-level accessor functions, an object can be minimally manipulated from the target language using code like this:
v = new_Vector()
Vector_x_set(v, 2)
Vector_y_set(v, 10)
Vector_z_set(v, -5)
delete_Vector(v)
However, most of SWIG’s language modules also provide a high-level interface that is more convenient. Keep reading.
Structures involving character strings require some care.
SWIG assumes that all members of type char * have been dynamically allocated using malloc() and that they are NULL-terminated ASCII strings. For example :
%module mymodule
...
struct Foo {
char *name;
...
}
This results in the following accessor functions :
// Note: If the -c++ option is used, new and delete are used to perform memory allocation.
char *Foo_name_get(Foo *obj)
{
return Foo->name;
}
char *Foo_name_set(Foo *obj, char *c)
{
if (obj->name)
free(obj->name);
obj->name = (char *) malloc(strlen(c)+1);
strcpy(obj->name, c);
return obj->name;
}
If this behavior differs from what you need in your applications, the SWIG “memberin” typemap can be used to change it. See the typemaps chapter for further details.
Arrays may appear as the members of structures, but they will be read-only by default. SWIG may generate a warning message:
interface.i:116. Warning. Array member will be read-only
To eliminate the warning message, typemaps can be used, but this is discussed in a later chapter. In many cases, the warning message is harmless.
5.5.4 Structure data members Occasionally, a structure will contain data members that are themselves structures. For example:
typedef struct Foo
{
int x;
} Foo;
typedef struct Bar
{
int y;
Foo f; /* Structure data member */
} Bar;
When a structure member is wrapped, it is handled as a pointer, unless the %naturalvar directive is used where it is handled more like a C++ reference (see C++ Member data).
The accessors to the member variable as a pointer are effectively wrapped as follows:
Foo *Bar_f_get(Bar *b)
{
return &b->f;
}
void Bar_f_set(Bar *b, Foo *value)
{
b->f = *value;
}
The reasons for this are have to do with the problem of modifying and accessing data inside the data member. For example, suppose you wanted to modify f.x in C like this:
Bar *b;
b->f.x = 37;
Translating them to function calls in C (as would be used inside the scripting language interface) results in the following code:
Bar *b;
Foo_x_set(Bar_f_get(b), 37);
In this code, if the Bar_f_get() function were to return a Foo instead of a Foo*, then the resulting modification would be applied to a copy of f and not the data member f itself. Clearly that’s not what you want!
It should be noted that this transformation to pointers only occurs if SWIG knows that a data member is a structure or class. For instance, if you had a structure like this,
struct Foo
{
WORD w;
};
and nothing was known about WORD, then SWIG will generate more normal accessor functions like this:
WORD Foo_w_get(Foo *f)
{
return f->w;
}
void Foo_w_set(FOO *f, WORD value)
{
f->w = value;
}
Compatibility Note: if you need to tell SWIG that an undeclared datatype is really a struct, simply use a forward struct declaration such as “struct Foo;”.
When wrapping structures, it is generally useful to have a mechanism for creating and destroying objects
As there may be memory allocations happening when constructing structures that should be released when destruction.
SWIG will by default automatically generate functions for creating and destroying objects using malloc() and free() when SWIG is used on C code, with C++ being handled differently.
If you don’t want SWIG to generate default constructors for your interfaces,
you can use the %nodefaultctor
directive or the -nodefaultctor
command line option. For example:
swig -nodefaultctor example.i
or
%module foo
...
%nodefaultctor; // Don't create default constructors
... declarations ...
%clearnodefaultctor; // Re-enable default constructors
If you need more precise control, %nodefaultctor
can selectively target
individual structure definitions. For example:
%nodefaultctor Foo; // No default constructor for Foo
...
struct Foo
{
// No default constructor generated.
};
struct Bar
{
// Default constructor generated.
};
Since ignoring the implicit or default destructors most of the time produces memory leaks, SWIG will always try to generate them.
If needed, however, you can selectively disable the generation of the
default/implicit destructor by using %nodefaultdtor
:
%nodefaultdtor Foo; // No default/implicit destructor for Foo
...
struct Foo
{
// No default destructor is generated.
};
struct Bar
{
// Default destructor generated.
};
Note: There are also the -nodefault
option and %nodefault
directive,
which disable both the default or implicit destructor generation.
This could lead to memory leaks across the target languages,
and it is highly recommended you don’t use them.
SWIG provides a special %extend directive that makes it possible to attach methods to C structures for purposes of building an object oriented interface. Suppose you have a C header file with the following declaration :
/* file : vector.h */
...
typedef struct Vector
{
double x, y, z;
} Vector;
You can make a Vector look a lot like a class by writing a SWIG interface like this:
// file : vector.i
%module mymodule
%{
#include "vector.h"
%}
%include "vector.h" // Just grab original C header file
%extend Vector
{
// Attach these functions to struct Vector.
// The newly constructed object must be returned as if the constructor
// declaration had a return value, a Vector * in this case.
Vector(double x, double y, double z)
{
Vector *v;
v = (Vector *) malloc(sizeof(Vector));
v->x = x;
v->y = y;
v->z = z;
return v;
}
~Vector()
{
free($self);
}
double magnitude()
{
return sqrt($self->x*$self->x+$self->y*$self->y+$self->z*$self->z);
}
void print()
{
printf("Vector [%g, %g, %g]\n", $self->x, $self->y, $self->z);
}
};
Note the usage of the $self
special variable. Its usage is identical to a
C++ ‘this’ pointer and should be used whenever access to the struct
instance is required.
Now, when used with proxy classes in Python, you can do things like this :
v = Vector(3, 4, 0) # Create a new vector
print v.magnitude() # Print magnitude
# 5.0
v.print() # Print it out
# [ 3, 4, 0 ]
del v # Destroy it
The %extend directive can also be used inside the definition of the Vector structure. For example:
// file : vector.i
%module mymodule
%{
#include "vector.h"
%}
typedef struct Vector {
double x, y, z;
%extend {
Vector(double x, double y, double z) { ... }
~Vector() { ... }
...
}
} Vector;
Note that %extend can be used to access externally written functions provided they follow the naming convention used in this example :
/* File : vector.c */
/* Vector methods */
#include "vector.h"
Vector *new_Vector(double x, double y, double z) {
Vector *v;
v = (Vector *) malloc(sizeof(Vector));
v->x = x;
v->y = y;
v->z = z;
return v;
}
void delete_Vector(Vector *v) {
free(v);
}
double Vector_magnitude(Vector *v) {
return sqrt(v->x*v->x+v->y*v->y+v->z*v->z);
}
// File : vector.i
// Interface file
%module mymodule
%{
#include "vector.h"
%}
typedef struct Vector {
double x, y, z;
%extend {
Vector(int, int, int); // This calls new_Vector()
~Vector(); // This calls delete_Vector()
double magnitude(); // This will call Vector_magnitude()
...
}
} Vector;
The name used for %extend should be the name of the struct and not the name of any typedef to the struct. For example:
typedef struct Integer {
int value;
} Int;
%extend Integer { ... } /* Correct name */
%extend Int { ... } /* Incorrect name */
struct Float {
float value;
};
typedef struct Float FloatValue;
%extend Float { ... } /* Correct name */
%extend FloatValue { ... } /* Incorrect name */
There is one exception to this rule and that is when the struct is anonymously named such as:
typedef struct {
double value;
} Double;
%extend Double { ... } /* Okay */
A little known feature of the %extend
directive is that it can also be used
to add synthesized attributes or to modify the behavior of existing data
attributes.
For example, suppose you wanted to make magnitude a read-only attribute of Vector instead of a method. To do this, you might write some code like this:
// Add a new attribute to Vector
%extend Vector {
const double magnitude;
}
// Now supply the implementation of the Vector_magnitude_get function
%{
const double Vector_magnitude_get(Vector *v) {
return (const double) sqrt(v->x*v->x+v->y*v->y+v->z*v->z);
}
%}
Now, for all practical purposes, magnitude will appear like an attribute of the object.
A similar technique can also be used to work with data members that you want to process. For example, consider this interface:
typedef struct Person {
char name[50];
...
} Person;
Say you wanted to ensure name was always upper case, you can rewrite the interface as follows to ensure this occurs whenever a name is read or written to:
typedef struct Person {
%extend {
char name[50];
}
...
} Person;
%{
#include <string.h>
#include <ctype.h>
void make_upper(char *name) {
char *c;
for (c = name; *c; ++c)
*c = (char)toupper((int)*c);
}
/* Specific implementation of set/get functions forcing capitalization */
char *Person_name_get(Person *p) {
make_upper(p->name);
return p->name;
}
void Person_name_set(Person *p, char *val) {
strncpy(p->name, val, 50);
make_upper(p->name);
}
%}
Note: it should be stressed that even though %extend
can be used to
add new data members, these new members can not require the allocation
of additional storage in the object (e.g., their values must be entirely
synthesized from existing attributes of the structure or obtained elsewhere).
Occasionally, a C program will involve structures like this :
typedef struct Object {
int objtype;
union {
int ivalue;
double dvalue;
char *strvalue;
void *ptrvalue;
} intRep;
} Object;
When SWIG encounters this, it performs a structure splitting operation that transforms the declaration into the equivalent of the following:
typedef union {
int ivalue;
double dvalue;
char *strvalue;
void *ptrvalue;
} Object_intRep;
typedef struct Object {
int objType;
Object_intRep intRep;
} Object;
SWIG will then create an Object_intRep structure for use inside the interface file. Accessor functions will be created for both structures. In this case, functions like this would be created :
Object_intRep *Object_intRep_get(Object *o)
{
return (Object_intRep *) &o->intRep;
}
int Object_intRep_ivalue_get(Object_intRep *o)
{
return o->ivalue;
}
int Object_intRep_ivalue_set(Object_intRep *o, int value)
{
return (o->ivalue = value);
}
double Object_intRep_dvalue_get(Object_intRep *o)
{
return o->dvalue;
}
... etc ...
Although this process is a little hairy, it works like you would expect in the target scripting language–especially when proxy classes are used. For instance, in Perl:
# Perl5 script for accessing nested member
$o = CreateObject(); # Create an object somehow
$o->{intRep}->{ivalue} = 7 # Change value of o.intRep.ivalue
Note: if you have a lot of nested structure declarations, it is advisable to double-check them after running SWIG. Nesting is handled differently in C++ mode, see Nested classes.
Sometimes it is necessary to insert special code into the resulting wrapper file generated by SWIG. For example, you may want to include additional C code to perform initialization or other operations.
There are four common ways to insert code, but it’s useful to know how the output of SWIG is structured first.
When SWIG creates its output C/C++ file, it is broken up into five sections:
The %insert directive enables inserting blocks of code into a given section of the generated code. It can be used in one of two ways:
%insert("section") "filename"
%insert("section") %{ ... %}
For example, %runtime is used instead of %insert(“runtime”). The valid sections and order of the sections in the generated C/C++ wrapper file is as shown:
%begin %{
... code in begin section ...
%}
%runtime %{
... code in runtime section ...
%}
%header %{
... code in header section ...
%}
%wrapper %{
... code in wrapper section ...
%}
%init %{
... code in init section ...
%}
Note: the bare %{ … %} directive is a shortcut that is the same as
%header %{ ... %}
.
A common use for code blocks is to write “helper” functions. These are functions that are used specifically for the purpose of building an interface, but which are generally not visible to the normal C program. For example:
%{
/* Create a new vector */
static Vector *new_Vector()
{
return (Vector *) malloc(sizeof(Vector));
}
%}
// Now tell SWIG to warp and expose it to script world
Vector *new_Vector();
Since the process of writing helper functions is fairly common, there is a special inlined form of code block that is used as follows :
%inline
%{
// Create a new vector and at the same time
// tell SWIG to warp and expose it to script world
Vector *new_Vector()
{
return (Vector *) malloc(sizeof(Vector));
}
%}
The %inline directive inserts all of the code that follows verbatim into the header portion of an interface file.
The code is then parsed by both the SWIG preprocessor and parser. Thus, the above example creates a new command new_Vector using only one declaration.
When code is included in the %init section, it is copied directly into the module initialization function. For example, if you needed to perform some extra initialization on module loading, you could write this:
%init %{init_variables();%}
This section describes the general approach for building interfaces with SWIG. The specifics related to a particular scripting language are found in later chapters.
Here’s a series of steps you can follow to make an interface for a C program :
Note: In the process of building an interface, SWIG may encounter syntax errors or other problems. The best way to deal with this is to simply copy the offending code into a separate interface file and edit it.
The preferred method of using SWIG is to generate a separate interface file. Suppose you have the following C header file :
/* File : header.h */
#include <stdio.h>
#include <math.h>
extern int foo(double);
extern double bar(int, int);
extern void dump(FILE *f);
A typical SWIG interface file for this header file would look like the following :
/* File : interface.i */
%module mymodule
%{
#include "header.h"
%}
extern int foo(double);
extern double bar(int, int);
extern void dump(FILE *f);
Of course, in this case, our header file is pretty simple so we could use a simpler approach and use an interface file like this:
/* File : interface.i */
%module mymodule
%{
#include "header.h"
%}
%include "header.h"
The main advantage of this approach is minimal maintenance of an interface file for when the header file changes in the future.
Note: in more complex projects, an interface file containing numerous %include and #include statements like this is one of the most common approaches to interface file design due to lower maintenance overhead.
Although SWIG can parse many header files, it is more common to write a special .i file defining the interface to a package. There are several reasons why you might want to do this:
Note: Sometimes, it is necessary to use certain header files in order for the code generated by SWIG to compile properly. Make sure you include certain header files by using a %{ %} block like this:
%module graphics
%{
#include <GL/gl.h>
#include <GL/glu.h>
%}
// Put the rest of the declarations here
...
If your program defines a main() function, you may need to get rid of it or rename it in order to use a scripting language. As most scripting languages define their own main() procedure that is called instead.
main() also makes no sense when working with dynamic loading. There are a few approaches to solving the main() conflict :
Note: getting rid of main() may cause potential initialization problems of a program. To handle this problem, you may consider writing a special function called program_init() that initializes your program upon startup.
This function could then be called either from the scripting language as the first operation, or when the SWIG generated module is loaded. In many cases, the old main() program can be completely replaced by a Perl, Python, or Tcl script.
a single writer and a single reader via shared-memory ?
two fifo q1 and q2 used to simlate biodirectional data flows bwtween p1 and p2.
no lock required at all. queue refers to linux lock free queue.
q1: t1 as writer and t2 as reader so single data flow p1—>p2
q2: t1 as reader and t2 as writer so single data flow p1<—p2
when writer writes all buffer, return error code of ENOBUF to caller just as socket does
这种单独单写的连原子操作都不需要,更不要说mutex之类的了。
假设A,B两进程通信
首先,将共享内存区域分成n块,如何分自己定义。
其次,每块内存指定一个byte做标志,
定义为: 0为A可读写状态,B不可读写;
1为B可读写状态,A不可读写。
A的行为:
遍历n块内存,找到一个标志为0的:
接收:
查看是否有B发来的消息,有,则接收,设置为可发送状态;
发送:消息复制到该块区域,设置标志为1;
B的行为:
遍历n块内存,找到一个标志为1的:
接收:
查看是否有B发来的消息,有,则接收,设置为可发送状态;
发送:消息复制到该块区域,设置标志为0;
There are two reasons computers use the binary system: Two clearly distinct states that provide a safety range for reliability. Least amount of necessary circuitry, which results in the least amount of space, energy consumption, and cost.
Want to practice converting binary numbers?
Try the Cisco Binary Numbers Game
Penjee’s adaptation of the Cisco Binary Numbers Game How Binary Numbers Game Works
binary, computer science, digital electronics.Posted on March 5, 2015 by Thomas N What does a Binary Number Mean?Penjee Quick Links Penjee App Programming Gifs AP Computer Science Pygame Tutorials © 2014 Penjee.com Learn to Code All Rights Reserved
:)
c++ calling script is also called callback because c++ calls script and then script calls c++ again.
Possible applications of SWIG include:
let’s list a few problems with C/C++ programming:
If you are a previous user of SWIG, don’t expect SWIG to provide complete backwards compatibility.
If you need to work with different versions of SWIG and backwards compatibility is an issue, you can use the SWIG_VERSION preprocessor symbol which holds the version of SWIG being executed.
SWIG_VERSION is a hexadecimal integer such as 0x010311 (corresponding to SWIG-1.3.11). This can be used in an interface file to define different typemaps, take advantage of different features etc:
#if SWIG_VERSION >= 0x010311
/*Use some fancy new feature */
#endif
If you checked the code out via Git, you will have to run ./autogen.sh before ./configure.
The Windows distribution is called swigwin and includes a prebuilt SWIG executable, swig.exe and so ypu do not need to compile it.
To build and install SWIG, simply type the following:
$ ./configure
$ make
$ make install
By default SWIG installs itself in /usr/local. If you need to install SWIG in a different location or in your home directory, use the –prefix option to ./configure. For example:
$ ./configure --prefix=/home/yourname/projects
$ make
$ make install
Note: the directory given to –prefix must be an absolute pathname. Do not use the ~ shell-escape to refer to your home directory. SWIG won’t work properly if you do this.
if you want to test SWIG after building it, a check can be performed on Unix operating systems.
Type the following: $ make -k check
you can use parallel make to speed up the check as it does take quite some
time to run, for example: $ make -j2 -k check
Even if the check fails, there is a pretty good chance SWIG still works correctly — you will just have to mess around with one of the examples and some makefiles to get it to work.
Some tests may also fail due to missing dependency packages, eg PCRE or Boost, but this will require careful analysis of the configure output done during configuration.
The Examples directory also includes Visual C++ project 6 (.dsp) files for building some of the examples on Windows. Later versions of Visual Studio will convert these old style project files into a current solution file.
Ensure the SWIG executable is as supplied in the SWIG root directory in order for the examples to work. Most languages require some environment variables to be set before running Visual C++. Note that Visual C++ must be re-started to pick up any changes in environment variables.
Open up an example .dsp file, Visual C++ will create a workspace for you (.dsw file). Ensure the Release build is selected then do a Rebuild All from the Build menu. The required environment variables are displayed with their current values.
Python
PYTHON_INCLUDE : Set this to the directory that contains Python.h
PYTHON_LIB : Set this to the python library including path for linking
Example using Python 2.1.1:
PYTHON_INCLUDE: D:\python21\include
PYTHON_LIB: D:\python21\libs\python21.lib
In a nutshell, SWIG is a compiler that takes C/C++ declarations and creates the wrappers needed to access those declarations from other languages including Perl, Python, Tcl, Ruby, Guile, and Java.
c++ calling script is also called callback because c++ calls script and then script calls c++ again.
Possible applications of SWIG include:
let’s list a few problems with C/C++ programming:
If you are a previous user of SWIG, don’t expect SWIG to provide complete backwards compatibility.
If you need to work with different versions of SWIG and backwards compatibility is an issue, you can use the SWIG_VERSION preprocessor symbol which holds the version of SWIG being executed.
SWIG_VERSION is a hexadecimal integer such as 0x010311 (corresponding to SWIG-1.3.11). This can be used in an interface file to define different typemaps, take advantage of different features etc:
#if SWIG_VERSION >= 0x010311
/*Use some fancy new feature */
#endif
If you checked the code out via Git, you will have to run ./autogen.sh before ./configure.
The Windows distribution is called swigwin and includes a prebuilt SWIG executable, swig.exe and so ypu do not need to compile it.
To build and install SWIG, simply type the following:
$ ./configure
$ make
$ make install
By default SWIG installs itself in /usr/local. If you need to install SWIG in a different location or in your home directory, use the –prefix option to ./configure. For example:
$ ./configure --prefix=/home/yourname/projects
$ make
$ make install
Note: the directory given to –prefix must be an absolute pathname. Do not use the ~ shell-escape to refer to your home directory. SWIG won’t work properly if you do this.
if you want to test SWIG after building it, a check can be performed on Unix operating systems.
Type the following: $ make -k check
you can use parallel make to speed up the check as it does take quite some
time to run, for example: $ make -j2 -k check
Even if the check fails, there is a pretty good chance SWIG still works correctly — you will just have to mess around with one of the examples and some makefiles to get it to work.
Some tests may also fail due to missing dependency packages, eg PCRE or Boost, but this will require careful analysis of the configure output done during configuration.
The Examples directory also includes Visual C++ project 6 (.dsp) files for building some of the examples on Windows. Later versions of Visual Studio will convert these old style project files into a current solution file.
Ensure the SWIG executable is as supplied in the SWIG root directory in order for the examples to work. Most languages require some environment variables to be set before running Visual C++. Note that Visual C++ must be re-started to pick up any changes in environment variables.
Open up an example .dsp file, Visual C++ will create a workspace for you (.dsw file). Ensure the Release build is selected then do a Rebuild All from the Build menu. The required environment variables are displayed with their current values.
Python
PYTHON_INCLUDE : Set this to the directory that contains Python.h
PYTHON_LIB : Set this to the python library including path for linking
Example using Python 2.1.1:
PYTHON_INCLUDE: D:\python21\include
PYTHON_LIB: D:\python21\libs\python21.lib