From 5dba60943c038b178faf55b5ea03ef09798965ac Mon Sep 17 00:00:00 2001
From: William S Fulton 37 SWIG and Scilab
+39 SWIG and Scilab
@@ -21,16 +21,28 @@
-
-
SWIG for Scilab supports Linux. Other operating sytems haven't been tested. @@ -92,7 +104,8 @@ SWIG for Scilab supports C language. C++ is partially supported. See 37.2 Running SWIG +
Let's see how to use SWIG for Scilab on a small example. @@ -125,7 +138,8 @@ Note: a code in an %inline section is both parsed and wrapped by SWIG,
-The module is generated using the swig executable and its -scilab option. @@ -145,7 +159,7 @@ This command generates two files:
Note: if the following error is returned: -
+
:1: Error: Unable to find 'swig.swg' @@ -167,7 +181,8 @@ The swig executable has several other command line options you can use. -37.2.2 Building the module
+39.2.2 Building the module
+To be loaded in Scilab, the wrapper has to be built into a dynamic module (or shared library). @@ -186,7 +201,8 @@ $ gcc -shared example_wrap.o -o libexample.so Note: we supposed in this example that the path to the Scilab include directory is /usr/local/include/scilab (which is the case in a Debian environment), this should be changed for another environment.
-37.2.3 Loading the module
+39.2.3 Loading the module
+Loading a module is done by running the loader script in Scilab: @@ -209,7 +225,8 @@ Link done. which means that Scilab has successfully loaded the shared library. The module functions and other symbols are now available in Scilab.
-37.2.4 Using the module
+39.2.4 Using the module
+In Scilab, the function fact() is simply called as following: @@ -242,7 +259,8 @@ ans = Note: for conciseness, we assume in the subsequent Scilab code examples that the modules have been beforehand built and loaded in Scilab.
-37.2.5 Scilab command line options
+39.2.5 Scilab command line options
+The following table lists the Scilab specific command line options in addition to the generic SWIG options: @@ -296,17 +314,20 @@ $ swig -scilab -help
SWIG for Scilab provides only a low-level C interface for Scilab (see Scripting Languages for the general approach to wrapping). This means that functions, structs, classes, variables, etc... are interfaced through C functions. These C functions are mapped as Scilab functions. There are a few exceptions, such as constants and enumerations, which can be wrapped directly as Scilab variables. -
+
+ +In Scilab 5.x, identifier names are composed of 24 characters maximum (this limitation should disappear from Scilab 6.0 onwards). @@ -314,9 +335,9 @@ In Scilab 5.x, identifier names are composed of 24 characters maximum (this limi
This happens especially when wrapping structs/classes, for which the wrapped function name is composed of the struct/class name and field names. In these cases, the %rename directive can be used to choose a different Scilab name. -
+
-@@ -347,7 +368,8 @@ ans = 24. -
In the above example, the function parameter is a primitive type and is marshalled by value. @@ -399,7 +421,8 @@ In Scilab, parameters are passed by value. The output (and inout) parameters are 7. -
A C function can have several output parameters. They can all be returned as results of the wrapped function as Scilab supports multiple return values from a function @@ -431,6 +454,8 @@ int divide(int n, int d, int q*, int *r) {
+
+--> [ret, q, r] = divide(20, 6) r = @@ -443,10 +468,10 @@ int divide(int n, int d, int q*, int *r) { 1.
Global variables are manipulated through generated accessor functions. @@ -514,9 +539,11 @@ It works the same:
-There is not any constant in Scilab. By default, C/C++ constants are wrapped as getter functions. For example, for the following constants: @@ -656,7 +683,8 @@ are mapped to Scilab variables, with the same name: 3.14 -
The wrapping of enums is the same as for constants. @@ -700,6 +728,8 @@ typedef enum { RED, BLUE, GREEN } color;
+
+--> exec loader.sce; --> RED @@ -718,9 +748,9 @@ typedef enum { RED, BLUE, GREEN } color; 2.
C/C++ pointers are fully supported by SWIG. They are mapped to the Scilab pointer type ("pointer", type ID: 128). @@ -761,7 +791,8 @@ These functions can be used in a natural way from Scilab: The user of a pointer is responsible for freeing it or, like in the example, closing any resources associated with it (just as is required in a C program).
-Most of time pointer manipulation is not needed in a scripting language such as Scilab. @@ -770,11 +801,11 @@ However, in some cases it can be useful, such as for testing or debugging.
SWIG comes with two pointer utility functions: +
Following illustrates their use on the last example:
@@ -791,7 +822,8 @@ SWIG comes with two pointer utility functions: --> fclose(f); -By default, Scilab does not provide a way to test or create null pointers.
But it is possible to have a null pointer by using the previous functions SWIG_this() and SWIG_ptr(), like this:
@@ -806,7 +838,7 @@ But it is possible to have a null pointer by using the previous functions SW
-37.3.7 Structures
+39.3.7 Structures
@@ -834,13 +866,13 @@ typedef struct {
Several functions are generated: +
Usage example: @@ -865,7 +897,7 @@ ans =
-Members of a structure that are also structures are also accepted and wrapped as a pointer:
+Members of a structure that are also structures are also accepted and wrapped as a pointer:@@ -885,6 +917,8 @@ typedef struct {
+
+--> b = new_Bar(); --> Bar_x_set(b, 20.); @@ -898,10 +932,10 @@ ans = 20.
Classes do not exist in Scilab. The classes are wrapped the same way as structs. @@ -922,7 +956,7 @@ class Point { public: int x, y; Point(int _x, int _y) : x(_x), y(_y) {} - double distance(const Point& rhs) { + double distance(const Point& rhs) { return sqrt(pow(x-rhs.x, 2) + pow(y-rhs.y, 2)); } void set(int _x, int _y) { @@ -950,7 +984,8 @@ ans = --> delete_Point(p2); -
Inheritance is supported. SWIG knows the inheritance relationship between classes. @@ -1024,7 +1059,8 @@ But we can use either use the get_perimeter() function of the parent cl 18.84 -
In C++ objects can be passed by value, pointer, reference, or by an array: @@ -1044,8 +1080,8 @@ public: int x; }; -void spam1(Foo *f) { sciprint("%d\n", f->x); } // Pass by pointer -void spam2(Foo &f) { sciprint("%d\n", f.x); } // Pass by reference +void spam1(Foo *f) { sciprint("%d\n", f->x); } // Pass by pointer +void spam2(Foo &f) { sciprint("%d\n", f.x); } // Pass by reference void spam3(Foo f) { sciprint("%d\n", f.x); } // Pass by value void spam4(Foo f[]) { sciprint("%d\n", f[0].x); } // Array of objects @@ -1081,7 +1117,8 @@ All these functions will return a pointer to an instance of Foo. As the function spam7 returns a value, new instance of Foo has to be allocated, and a pointer on this instance is returned.
-As in other languages, function and class templates are supported in SWIG Scilab. @@ -1140,7 +1177,8 @@ Then in Scilab: More details on template support can be found in the templates documentation.
-C++ operators are partially supported. @@ -1164,7 +1202,7 @@ class Complex { public: Complex(double re, double im) : real(re), imag(im) {}; - Complex operator+(const Complex& other) { + Complex operator+(const Complex& other) { double result_real = real + other.real; double result_imaginary = imag + other.imag; return Complex(result_real, result_imaginary); @@ -1179,6 +1217,8 @@ private:
+
+--> c1 = new_Complex(3, 7); @@ -1189,10 +1229,10 @@ private: 4.
SWIG is aware of C++ namespaces, but does not use it for wrappers. @@ -1209,7 +1249,7 @@ For example with one namespace Foo: namespace foo { int fact(int n) { - if (n > 1) + if (n > 1) return n * fact(n-1); else return 1; @@ -1269,7 +1309,8 @@ Note: the nspace feature is
-Scilab does not natively support exceptions, but has errors. @@ -1288,19 +1329,19 @@ void throw_exception() throw(char const *) {
+
+-->throw_exception() !--error 999 SWIG/Scilab: Exception (char const *) occured: Bye world !
Scilab has a try-catch mechanism (and a similar instruction execstr()) to handle exceptions. It can be used with the lasterror() function as following:
-
--> execstr('throw_exception()', 'errcatch'); ans = @@ -1312,7 +1353,6 @@ It can be used with the lasterror() function as following: SWIG/Scilab: Exception (char const *) occured: Bye world !
If the function has a throw exception specification, SWIG can automatically map the exception type and set an appropriate Scilab error message. @@ -1330,13 +1370,15 @@ void throw_int() throw(int) { } void throw_stl_invalid_arg(int i) throw(std::invalid_argument) { - if (i < 0) + if (i < 0) throw std::invalid_argument("argument is negative."); } %}
+
+--> throw_int(); !--error 999 @@ -1346,29 +1388,31 @@ SWIG/Scilab: Exception (int) occured: 12 !--error 999 SWIG/Scilab: ValueError: argument is negative.
More complex or custom exception types require specific exception typemaps to be implemented in order to specifically handle a thrown type. See the SWIG C++ documentation for more details. -
+
+ +The Standard Template Library (STL) is partially supported. See STL for more details.
-The following table provides the equivalent Scilab type for C/C++ primitive types.
C/C++ type | Scilab type | @@ -1393,6 +1437,7 @@ The following table provides the equivalent Scilab type for C/C++ primitive type