A hint: This file contains one or more very long lines, so maybe it is better readable using the pure text view mode that shows the contents as wrapped lines within the browser window.
1 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> 2 <html> 3 <head> 4 <title>SWIG and Scilab</title> 5 <link rel="stylesheet" type="text/css" href="style.css"> 6 <meta http-equiv="content-type" content="text/html; charset=UTF-8"> 7 </head> 8 9 10 <body bgcolor="#ffffff"> 11 12 <H1><a name="Scilab">36 SWIG and Scilab</a></H1> 13 <!-- INDEX --> 14 <div class="sectiontoc"> 15 <ul> 16 <li><a href="#Scilab_preliminaries">Preliminaries</a> 17 <li><a href="#Scilab_running_swig">Running SWIG</a> 18 <ul> 19 <li><a href="#Scilab_running_swig_generating_module">Generating the module</a> 20 <li><a href="#Scilab_running_swig_building_module">Building the module</a> 21 <li><a href="#Scilab_running_swig_loading_module">Loading the module</a> 22 <li><a href="#Scilab_running_swig_using_module">Using the module</a> 23 <li><a href="#Scilab_running_swig_options">Scilab command line options</a> 24 </ul> 25 <li><a href="#Scilab_wrapping">A basic tour of C/C++ wrapping</a> 26 <ul> 27 <li><a href="#Scilab_wrapping_overview">Overview</a> 28 <li><a href="#Scilab_wrapping_identifiers">Identifiers</a> 29 <li><a href="#Scilab_wrapping_functions">Functions</a> 30 <ul> 31 <li><a href="#Scilab_nn13">Argument passing</a> 32 <li><a href="#Scilab_nn14">Multiple output arguments</a> 33 </ul> 34 <li><a href="#Scilab_wrapping_global_variables">Global variables</a> 35 <li><a href="#Scilab_wrapping_constants_and_enums">Constants and enumerations</a> 36 <ul> 37 <li><a href="#Scilab_wrapping_constants">Constants</a> 38 <li><a href="#Scilab_wrapping_enums">Enumerations</a> 39 </ul> 40 <li><a href="#Scilab_wrapping_pointers">Pointers</a> 41 <ul> 42 <li><a href="#Scilab_wrapping_pointers_utility_functions">Utility functions</a> 43 <li><a href="#Scilab_wrapping_pointers_null_pointers">Null pointers:</a> 44 </ul> 45 <li><a href="#Scilab_wrapping_structs">Structures</a> 46 <li><a href="#Scilab_wrapping_cpp_classes">C++ classes</a> 47 <li><a href="#Scilab_wrapping_cpp_inheritance">C++ inheritance</a> 48 <li><a href="#Scilab_wrapping_cpp_overloading">C++ overloading</a> 49 <li><a href="#Scilab_wrapping_pointers_references_values_arrays">Pointers, references, values, and arrays</a> 50 <li><a href="#Scilab_wrapping_cpp_templates">C++ templates</a> 51 <li><a href="#Scilab_wrapping_cpp_operators">C++ operators</a> 52 <li><a href="#Scilab_wrapping_cpp_namespaces">C++ namespaces</a> 53 <li><a href="#Scilab_wrapping_cpp_exceptions">C++ exceptions</a> 54 <li><a href="#Scilab_wrapping_cpp_stl">C++ STL</a> 55 </ul> 56 <li><a href="#Scilab_typemaps">Type mappings and libraries</a> 57 <ul> 58 <li><a href="#Scilab_typemaps_primitive_types">Default primitive type mappings</a> 59 <li><a href="#Scilab_typemaps_arrays">Arrays</a> 60 <li><a href="#Scilab_typemaps_pointer-to-pointers">Pointer-to-pointers</a> 61 <li><a href="#Scilab_typemaps_matrices">Matrices</a> 62 <li><a href="#Scilab_typemaps_stl">STL</a> 63 </ul> 64 <li><a href="#Scilab_module_initialization">Module initialization</a> 65 <li><a href="#Scilab_building_modes">Building modes</a> 66 <ul> 67 <li><a href="#Scilab_building_modes_nobuilder_mode">No-builder mode</a> 68 <li><a href="#Scilab_building_modes_builder_mode">Builder mode</a> 69 </ul> 70 <li><a href="#Scilab_generated_scripts">Generated scripts</a> 71 <ul> 72 <li><a href="#Scilab_generated_scripts_builder_script">Builder script</a> 73 <li><a href="#Scilab_generated_scripts_loader_script">Loader script</a> 74 </ul> 75 <li><a href="#Scilab_other_resources">Other resources</a> 76 </ul> 77 </div> 78 <!-- INDEX --> 79 80 81 82 <p> 83 Scilab is a scientific software package for numerical computations providing a powerful open computing environment for engineering and scientific applications that is mostly compatible with MATLAB. More information can be found at <a href="https://www.scilab.org">www.scilab.org</a>. 84 </p> 85 86 <p> 87 This chapter explains how to use SWIG for Scilab. After this introduction, you should be able to generate with SWIG a Scilab external module from a C/C++ library. 88 </p> 89 90 91 <H2><a name="Scilab_preliminaries">36.1 Preliminaries</a></H2> 92 93 94 <p> 95 SWIG for Scilab supports Linux. Other operating systems haven't been tested. 96 </p> 97 98 <p> 99 Scilab is supported from version 5.3.3 onwards. 100 The forthcoming version 6, as of January 2015, is also supported. 101 </p> 102 103 <p> 104 SWIG for Scilab supports C language. C++ is partially supported. See <a href="#Scilab_wrapping">A basic tour of C/C++ wrapping</a> for further details. 105 </p> 106 107 108 <H2><a name="Scilab_running_swig">36.2 Running SWIG</a></H2> 109 110 111 <p> 112 Let's see how to use SWIG for Scilab on a small example. 113 <br> 114 In this example we bind from C a function and a global variable into Scilab. The SWIG interface (stored in a file named <tt>example.i</tt>), is the following: 115 </p> 116 117 <div class="code"><pre> 118 %module example 119 120 %inline %{ 121 double Foo = 3.0; 122 123 int fact(int n) { 124 if (n < 0) { 125 return 0; 126 } 127 else if (n == 0) { 128 return 1; 129 } 130 else { 131 return n * fact(n-1); 132 } 133 } 134 %} 135 </pre></div> 136 137 <p> 138 Note: a code in an <tt>%inline</tt> section is both parsed and wrapped by SWIG, and inserted as is in the wrapper source file. 139 </p> 140 141 142 <H3><a name="Scilab_running_swig_generating_module">36.2.1 Generating the module</a></H3> 143 144 145 <p> 146 The module is generated using the <tt>swig</tt> executable and its <tt>-scilab</tt> option. 147 </p> 148 149 <div class="shell"><pre> 150 $ swig -scilab example.i 151 </pre></div> 152 153 <p> 154 This command generates two files: 155 </p> 156 <ul> 157 <li><tt>example_wrap.c</tt>: a C source file containing the wrapping code and also here the wrapped code (the <tt>fact()</tt> and <tt>Foo</tt> definitions)</li> 158 <li><tt>loader.sce</tt>: a Scilab script used to load the module into Scilab 159 </ul> 160 161 <p> 162 Note: if the following error is returned: 163 </p> 164 165 <div class="shell"><pre> 166 :1: Error: Unable to find 'swig.swg' 167 :3: Error: Unable to find 'scilab.swg' 168 </pre></div> 169 170 <p> 171 it may be because the SWIG library is not found. Check the <tt>SWIG_LIB</tt> environment variable or your SWIG installation. 172 </p> 173 174 <p> 175 Note: SWIG for Scilab can work in two modes related to the way the module is built, see the <a href="#Scilab_building_modes">Building modes</a> section for details. 176 This example uses the <tt>builder</tt> mode. 177 </p> 178 179 180 <p> 181 The <tt>swig</tt> executable has several other command line options you can use. See <a href="#Scilab_running_swig_options">Scilab command line options</a> for further details. 182 </p> 183 184 185 <H3><a name="Scilab_running_swig_building_module">36.2.2 Building the module</a></H3> 186 187 188 <p> 189 To be loaded in Scilab, the wrapper has to be built into a dynamic module (or shared library). 190 </p> 191 192 <p> 193 The commands to compile and link the wrapper (with <tt>gcc</tt>) into the shared library <tt>libexample.so</tt> are: 194 </p> 195 196 <div class="shell"><pre> 197 $ gcc -fPIC -c -I/usr/local/include/scilab example_wrap.c 198 $ gcc -shared example_wrap.o -o libexample.so 199 </pre></div> 200 201 <p> 202 Note: we supposed in this example that the path to the Scilab include directory is <tt>/usr/local/include/scilab</tt> (which is the case in a Debian environment), this should be changed for another environment. 203 </p> 204 205 <H3><a name="Scilab_running_swig_loading_module">36.2.3 Loading the module</a></H3> 206 207 208 <p> 209 Loading a module is done by running the loader script in Scilab: 210 </p> 211 212 <div class="targetlang"><pre> 213 --> exec loader.sce 214 </pre></div> 215 216 <p> 217 Scilab should output the following messages: 218 </p> 219 220 <div class="targetlang"><pre> 221 Shared archive loaded. 222 Link done. 223 </pre></div> 224 225 <p> 226 which means that Scilab has successfully loaded the shared library. The module functions and other symbols are now available in Scilab. 227 </p> 228 229 <H3><a name="Scilab_running_swig_using_module">36.2.4 Using the module</a></H3> 230 231 232 <p> 233 In Scilab, the function <tt>fact()</tt> is simply called as following: 234 </p> 235 236 <div class="targetlang"><pre> 237 --> fact(5) 238 ans = 239 240 120. 241 </pre></div> 242 243 <p>For the <tt>Foo</tt> global variable, the accessors need to be used: 244 245 <div class="targetlang"><pre> 246 --> Foo_get 247 ans = 248 249 3. 250 251 --> Foo_set(4); 252 253 --> Foo_get 254 ans = 255 256 4. 257 </pre></div> 258 259 <p> 260 Note: for conciseness, we assume in the subsequent Scilab code examples that the modules have been beforehand built and loaded in Scilab. 261 </p> 262 263 <H3><a name="Scilab_running_swig_options">36.2.5 Scilab command line options</a></H3> 264 265 266 <p> 267 The following table lists the Scilab specific command line options in addition to the generic SWIG options: 268 </p> 269 270 <table summary="Scilab specific options"> 271 272 <tr> 273 <td><tt>-builder</tt></td> 274 <td>Generate the Scilab builder script</td> 275 </tr> 276 277 <tr> 278 <td><tt>-buildercflags <cflags></tt></td> 279 <td>Add <cflags> to the builder compiler flags</td> 280 </tr> 281 282 <tr> 283 <td><tt>-builderldflags <ldflags></tt></td> 284 <td>Add <ldlags> to the builder linker flags</td> 285 </tr> 286 287 <tr> 288 <td><tt>-buildersources <files></tt></td> 289 <td>Add the (comma separated) files <files> to the builder sources</td> 290 </tr> 291 292 <tr> 293 <td><tt>-builderverbositylevel <level></tt></td> 294 <td>Set the build verbosity level to <level> (default 0: off, 2: high)</td> 295 </tr> 296 297 <tr> 298 <td><tt>-builderflagscript <file></tt></td> 299 <td>Use the Scilab script <file> to configure the compiler and linker flags</td> 300 </tr> 301 302 <tr> 303 <td><tt>-gatewayxml <gateway_id></tt></td> 304 <td>Generate the gateway XML with the given <gateway_id></td> 305 </tr> 306 307 </table> 308 309 <p> 310 These options can be displayed with: 311 </p> 312 313 <div class="shell"><pre> 314 $ swig -scilab -help 315 </pre></div> 316 317 318 <H2><a name="Scilab_wrapping">36.3 A basic tour of C/C++ wrapping</a></H2> 319 320 321 <H3><a name="Scilab_wrapping_overview">36.3.1 Overview</a></H3> 322 323 324 <p> 325 SWIG for Scilab provides only a low-level C interface for Scilab (see <a href="Scripting.html#Scripting">Scripting Languages</a> for the general approach to wrapping). 326 This means that functions, structs, classes, variables, etc... are interfaced through C functions. These C functions are mapped as Scilab functions. 327 There are a few exceptions, such as constants and enumerations, which can be wrapped directly as Scilab variables. 328 </p> 329 330 <H3><a name="Scilab_wrapping_identifiers">36.3.2 Identifiers</a></H3> 331 332 333 <p> 334 In Scilab 5.x, identifier names are composed of 24 characters maximum (this limitation disappears from Scilab 6.0 onwards). 335 <br>By default, variable, member, and function names longer than 24 characters are truncated, and a warning is produced for each truncation. 336 </p> 337 <p>This can cause ambiguities, especially when wrapping structs/classes, for which the wrapped function name is composed of the struct/class name and field names. 338 In these cases, the <a href="SWIG.html#SWIG_rename_ignore">%rename directive</a> can be used to choose a different Scilab name. 339 </p> 340 341 <H3><a name="Scilab_wrapping_functions">36.3.3 Functions</a></H3> 342 343 344 <p> 345 Functions are wrapped as new Scilab built-in functions. For example: 346 </p> 347 348 <div class="code"><pre> 349 %module example 350 351 %inline %{ 352 int fact(int n) { 353 if (n > 1) 354 return n * fact(n - 1); 355 else 356 return 1; 357 } 358 %} 359 </pre></div> 360 361 <p> 362 creates a built-in function <tt>fact(n)</tt> in Scilab: 363 </p> 364 365 <div class="targetlang"><pre> 366 --> fact(4) 367 ans = 368 369 24. 370 </pre></div> 371 372 <H4><a name="Scilab_nn13">36.3.3.1 Argument passing</a></H4> 373 374 375 <p> 376 In the above example, the function parameter is a primitive type and is marshalled by value. 377 So this function is wrapped without any additional customization. 378 Argument values are converted between C types and Scilab types through type mappings. 379 There are several default type mappings for primitive and complex types, described later in the <a href="#Scilab_typemaps">Scilab typemaps</a> section. 380 </p> 381 382 <p> 383 When a parameter is not passed by value, such as a pointer or reference, SWIG does not know if it is an input, output (or both) parameter. 384 The INPUT, OUTPUT, INOUT typemaps defined in the <tt>typemaps.i</tt> library can be used to specify this. 385 </p> 386 387 <p> 388 Let's see this on two simple functions: <tt>sub()</tt> which has an output parameter, and <tt>inc()</tt>, which as input/output parameter: 389 </p> 390 391 <div class="code"><pre> 392 %module example 393 394 %include <typemaps.i> 395 396 extern void sub(int *INPUT, int *INPUT, int *OUTPUT); 397 extern void inc(int *INOUT, int *INPUT); 398 399 %{ 400 void sub(int *x, int *y, int *result) { 401 *result = *x - *y; 402 } 403 void inc(int *x, int *delta) { 404 *x = *x + *delta; 405 } 406 %} 407 </pre></div> 408 409 <p> 410 In Scilab, parameters are passed by value. The output (and inout) parameters are returned as the result of the functions: 411 </p> 412 413 <div class="targetlang"><pre> 414 --> sub(5, 3) 415 ans = 416 417 2. 418 419 --> inc(4, 3) 420 ans = 421 422 7. 423 </pre></div> 424 425 <H4><a name="Scilab_nn14">36.3.3.2 Multiple output arguments</a></H4> 426 427 428 <p> 429 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 430 when using the <tt>typemaps.i</tt> library. 431 If the C function itself returns a result, this is returned first before the parameter outputs. 432 </p> 433 434 <p> 435 The example below shows this for a C function returning 2 values and a result: 436 </p> 437 438 <div class="code"><pre> 439 %module example 440 441 %include <typemaps.i> 442 443 int divide(int n, int d, int *OUTPUT, int *OUTPUT); 444 445 %{ 446 int divide(int n, int d, int q*, int *r) { 447 if (d != 0) { 448 *q = n / d; 449 *r = n % d; 450 return 1; 451 } else { 452 return 0; 453 } 454 } 455 %} 456 </pre></div> 457 458 <br/> 459 460 <div class="targetlang"><pre> 461 --> [ret, q, r] = divide(20, 6) 462 r = 463 464 2. 465 q = 466 467 3. 468 ret = 469 470 1. 471 </pre></div> 472 473 474 <H3><a name="Scilab_wrapping_global_variables">36.3.4 Global variables</a></H3> 475 476 477 <p> 478 Global variables are manipulated through generated accessor functions. 479 For example, for a given <tt>Foo</tt> global variable, SWIG actually generates two functions: <tt>Foo_get()</tt> to get the value of <tt>Foo</tt>, and <tt>Foo_set()</tt> to set the value. 480 These functions are used as following: 481 </p> 482 483 <div class="targetlang"><pre> 484 --> exec loader.sce; 485 --> c = Foo_get(); 486 487 --> Foo_set(4); 488 489 --> c 490 c = 491 492 3. 493 494 --> Foo_get() 495 ans = 496 497 4. 498 </pre></div> 499 500 <p> 501 It works for variables of primitive type, but also for non-primitive types: arrays, and structs/classes which are described later. 502 For now, an example with two global primitive arrays x and y is shown: 503 </p> 504 505 <div class="code"><pre> 506 %module example 507 508 %inline %{ 509 int x[10]; 510 double y[7]; 511 512 void initArrays() 513 { 514 int i; 515 for (i = 0; i < 10; i++) 516 x[i] = 1; 517 for (i = 0; i < 7; i++) 518 y[i] = 1.0f; 519 } 520 %} 521 </pre></div> 522 523 <p> 524 It works the same:</p> 525 526 <div class="targetlang"><pre> 527 --> exec loader.sce 528 529 --> initArrays(); 530 --> x_get() 531 ans = 532 533 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 534 535 --> y_set([0:6] / 10); 536 --> y_get() 537 ans = 538 539 0. 0.1 0.2 0.3 0.4 0.5 0.6 540 </pre></div> 541 542 543 <H3><a name="Scilab_wrapping_constants_and_enums">36.3.5 Constants and enumerations</a></H3> 544 545 546 <H4><a name="Scilab_wrapping_constants">36.3.5.1 Constants</a></H4> 547 548 549 <p> 550 There is not any constant in Scilab. By default, C/C++ constants are wrapped as getter functions. For example, for the following constants: 551 </p> 552 553 <div class="code"><pre> 554 %module example 555 #define ICONST 42 556 #define FCONST 2.1828 557 #define CCONST 'x' 558 #define CCONST2 '\n' 559 #define SCONST "Hello World" 560 #define SCONST2 "\"Hello World\"" 561 </pre></div> 562 563 <p> 564 the following getter functions are generated: 565 </p> 566 567 <div class="targetlang"><pre> 568 --> exec loader.sce; 569 --> ICONST_get(); 570 ans = 571 572 42. 573 574 --> FCONST_get(); 575 ans = 576 577 2.1828 578 579 --> CCONST_get(); 580 ans = 581 582 x 583 584 --> CCONST2_get(); 585 ans = 586 587 --> SCONST_get(); 588 ans = 589 590 Hello World 591 592 --> SCONST2_get(); 593 ans = 594 595 "Hello World" 596 597 --> EXPR_get(); 598 ans = 599 600 48.5484 601 602 --> iconst_get(); 603 ans = 604 605 37. 606 607 --> fconst_get(); 608 ans = 609 610 3.14 611 </pre></div> 612 613 <p> 614 There is another mode in which constants are wrapped as Scilab variables. 615 The variables are easier to use than functions, but the drawback is that variables are not constant and so can be modified. 616 </p> 617 618 <p> 619 This mode can be enabled/disabled at any time in the interface file with <tt>%scilabconst()</tt>, which 620 works like all the other <a href="Customization.html#Customization_features">%feature directives</a>. 621 Use the argument value "1" to enable and "0" to disable this mode. 622 For example in this mode the previous constants: 623 </p> 624 625 <div class="code"><pre> 626 %module example 627 628 %scilabconst(1); 629 #define ICONST 42 630 #define FCONST 2.1828 631 #define CCONST 'x' 632 #define CCONST2 '\n' 633 #define SCONST "Hello World" 634 #define SCONST2 "\"Hello World\"" 635 </pre></div> 636 637 <p> 638 are mapped to Scilab variables, with the same name: 639 </p> 640 641 <div class="targetlang"><pre> 642 --> exec loader.sce; 643 --> ICONST 644 ans = 645 646 42 647 648 --> FCONST 649 ans = 650 651 2.1828 652 653 --> CCONST 654 ans = 655 656 x 657 658 --> CCONST2 659 ans = 660 661 --> SCONST 662 ans = 663 664 Hello World 665 666 --> SCONST2 667 ans = 668 669 "Hello World" 670 671 --> EXPR 672 ans = 673 674 48.5484 675 676 --> iconst 677 ans = 678 679 37 680 681 --> fconst 682 ans = 683 684 3.14 685 </pre></div> 686 687 <H4><a name="Scilab_wrapping_enums">36.3.5.2 Enumerations</a></H4> 688 689 690 <p> 691 The wrapping of enums is the same as for constants. 692 By default, enums are wrapped as getter functions. 693 For example, with the following enumeration: 694 </p> 695 696 <div class="code"><pre>%module example 697 typedef enum { RED, BLUE, GREEN } color; 698 </pre></div> 699 700 <p> 701 a getter function will be generated for each value of the enumeration: 702 </p> 703 704 <div class="targetlang"><pre> 705 --> exec loader.sce; 706 --> RED_get() 707 ans = 708 709 0. 710 711 --> BLUE_get() 712 ans = 713 714 1. 715 716 --> GREEN_get() 717 ans = 718 719 2. 720 </pre></div> 721 722 <p> 723 The <tt>%scilabconst()</tt> feature is also available for enumerations: 724 </p> 725 726 <div class="code"><pre>%module example 727 %scilabconst(1) color; 728 typedef enum { RED, BLUE, GREEN } color; 729 </pre></div> 730 731 <br/> 732 733 <div class="targetlang"><pre> 734 --> exec loader.sce; 735 --> RED 736 ans = 737 738 0. 739 740 --> BLUE 741 ans = 742 743 1. 744 745 --> GREEN 746 ans = 747 748 2. 749 750 </pre></div> 751 752 <H3><a name="Scilab_wrapping_pointers">36.3.6 Pointers</a></H3> 753 754 755 <p> 756 Pointers are supported by SWIG. A pointer can be returned from a wrapped C/C++ function, stored in a Scilab variable, and used in input argument of another C/C++ function. 757 </p> 758 <p> 759 Also, thanks to the SWIG runtime which stores information about types, pointer types are tracked between exchanges Scilab and the native code. Indeed pointer types are stored alongside the pointer address. 760 A pointer is mapped to a Scilab structure (<a href="https://help.scilab.org/docs/5.5.2/en_US/tlist.html">tlist</a>), which contains as fields the pointer address and the pointer type (in fact a pointer to the type information structure in the SWIG runtime). 761 <br> 762 Why a native pointer is not mapped to a Scilab pointer (type name: "pointer", type ID: 128) ? The big advantage of mapping to a <tt>tlist</tt> is that it exposes a new type for the pointer in Scilab, type which can be accessed in Scilab with the <a href="https://help.scilab.org/docs/5.5.2/en_US/typeof.html">typeof</a> function, and manipulated using the <a href="https://help.scilab.org/docs/5.5.2/en_US/overloading.html">overloading</a> mechanism. 763 </p> 764 765 <p> 766 Notes: 767 </p> 768 <ul> 769 <li>type tracking needs the SWIG runtime to be first initialized with the appropriate function (see the <a href="#Scilab_module_initialization">Module initialization</a> section).</li> 770 <li>for any reason, if a wrapped pointer type is unknown (or if the SWIG runtime is not initialized), SWIG maps it to a Scilab pointer. Also, a Scilab pointer is always accepted as a pointer argument of a wrapped function. The drawback is that pointer type is lost.</li> 771 </ul> 772 773 <p> 774 Following is an example of the wrapping of the C <tt>FILE*</tt> pointer: 775 </p> 776 777 <div class="code"><pre> 778 %module example 779 780 %{ 781 #include <stdio.h> 782 %} 783 784 FILE *fopen(const char *filename, const char *mode); 785 int fputs(const char *, FILE *); 786 int fclose(FILE *); 787 </pre></div> 788 789 <p> 790 These functions can be used the same way as in C from Scilab: 791 </p> 792 793 <div class="targetlang"><pre> 794 --> example_Init(); 795 796 --> f = fopen("junk", "w"); 797 --> typeof(f) 798 ans = 799 800 _p_FILE 801 802 --> fputs("Hello World", f); 803 --> fclose(f); 804 </pre></div> 805 806 <p> 807 Note: the type name <tt>_p_FILE</tt> which means "pointer to FILE". 808 </p> 809 810 <p> 811 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). 812 </p> 813 814 <H4><a name="Scilab_wrapping_pointers_utility_functions">36.3.6.1 Utility functions</a></H4> 815 816 817 <p> 818 As a scripting language, Scilab does not provide functions to manipulate pointers. 819 However, in some cases it can be useful, such as for testing or debugging. 820 </p> 821 822 <p> 823 SWIG comes with two pointer utility functions: 824 </p> 825 <ul> 826 <li><tt>SWIG_this()</tt>: returns the address value of a pointer</li> 827 <li><tt>SWIG_ptr()</tt>: creates a pointer from an address value</li> 828 </ul> 829 830 <p> 831 Note: a pointer created by <tt>SWIG_ptr()</tt> does not have any type and is mapped as a Scilab pointer. 832 </p> 833 834 <p>Following we use the utility functions on the previous example:</p> 835 836 <div class="targetlang"><pre> 837 --> f = fopen("junk", "w"); 838 --> fputs("Hello", f); 839 --> addr = SWIG_this(f) 840 ans = 841 842 8219088. 843 844 --> p = SWIG_ptr(addr); 845 --> typeof(p) 846 ans = 847 848 pointer 849 850 --> fputs(" World", p); 851 --> fclose(f); 852 </pre></div> 853 854 855 <H4><a name="Scilab_wrapping_pointers_null_pointers">36.3.6.2 Null pointers:</a></H4> 856 857 858 <p> 859 Using the previous <tt>SWIG_this()</tt> and <tt>SWIG_ptr()</tt>, it is possible to create and check null pointers: 860 </p> 861 862 <div class="targetlang"><pre> 863 --> p = SWIG_ptr(0); 864 --> SWIG_this(p) == 0 865 ans = 866 867 T 868 </pre></div> 869 870 871 <H3><a name="Scilab_wrapping_structs">36.3.7 Structures</a></H3> 872 873 874 <p> 875 Structs exist in Scilab, but C structs are not (at least in this version of SWIG) mapped to Scilab structs. 876 A C structure is wrapped through low-level accessor functions, i.e. functions that give access to the member variables of this structure. 877 In Scilab, a structure is manipulated through a pointer which is passed as an argument to the accessor functions. 878 </p> 879 880 <p> 881 Let's see it on an example of a struct with two members: 882 </p> 883 884 <div class="code"><pre> 885 %module example 886 887 %inline %{ 888 889 typedef struct { 890 int x; 891 int arr[4]; 892 } Foo; 893 894 %} 895 </pre></div> 896 897 <p> 898 Several functions are generated: 899 </p> 900 <ul> 901 <li>a constructor function <tt>new_Foo()</tt> which returns a pointer to a newly created struct <tt>Foo</tt>.</li> 902 <li>two member getter functions <tt>Foo_x_get()</tt>, <tt>Foo_arr_get()</tt>, to get the values of <tt>x</tt> and <tt>y</tt> for the struct pointer (provided as the first parameter to these functions)</li> 903 <li>two member setter functions <tt>Foo_x_set()</tt>, <tt>Foo_arr_set()</tt>, to set the values of <tt>x</tt> and <tt>y</tt> for the struct pointer (provided as the first parameter to these functions).</li> 904 <li>a destructor function <tt>delete_Foo()</tt> to release the struct pointer.</li> 905 </ul> 906 907 908 <p> 909 Usage example: 910 </p> 911 912 <div class="targetlang"><pre> 913 --> f = new_Foo(); 914 --> Foo_x_set(f, 100); 915 --> Foo_x_get(f) 916 ans = 917 918 100. 919 920 --> Foo_arr_set(f, [0:3]); 921 --> Foo_arr_get(f) 922 ans = 923 924 0. 1. 2. 3. 925 926 --> delete_Foo(f); 927 </pre></div> 928 929 930 <p> 931 Members of a structure that are also structures are also accepted and wrapped as a pointer: 932 </p> 933 934 <div class="code"><pre> 935 %module example 936 937 %inline %{ 938 939 typedef struct { 940 int x; 941 } Bar; 942 943 typedef struct { 944 Bar b; 945 } Foo; 946 947 %} 948 </pre></div> 949 950 <br/> 951 952 <div class="targetlang"><pre> 953 --> b = new_Bar(); 954 --> Bar_x_set(b, 20.); 955 956 --> f = new_Foo(); 957 --> Foo_b_set(f, b); 958 959 --> b2 = Foo_b_get(f); 960 --> Bar_x_get(b2); 961 ans = 962 963 20. 964 </pre></div> 965 966 <p> 967 Note: the pointer to the struct works as described in <a href="#Scilab_wrapping_pointers">Pointers</a>. For example, the type of the struct pointer can be get with <tt>typeof</tt>, as following: 968 </p> 969 970 <div class="targetlang"><pre> 971 --> example_Init(); 972 --> b = new_Bar(); 973 --> typeof(b) 974 ans = 975 976 _p_Bar 977 --> delete_Bar(b); 978 </pre></div> 979 980 <H3><a name="Scilab_wrapping_cpp_classes">36.3.8 C++ classes</a></H3> 981 982 983 <p> 984 Classes do not exist in Scilab. The classes are wrapped the same way as structs. 985 Low-level accessor functions are generated for class members. 986 Also, constructor and destructor functions are generated to create and destroy an instance of the class. 987 </p> 988 989 <p> 990 For example, the following class: 991 </p> 992 993 <div class="code"><pre> 994 %module example 995 996 %inline %{ 997 998 class Point { 999 public: 1000 int x, y; 1001 Point(int _x, int _y) : x(_x), y(_y) {} 1002 double distance(const Point& rhs) { 1003 return sqrt(pow(x-rhs.x, 2) + pow(y-rhs.y, 2)); 1004 } 1005 void set(int _x, int _y) { 1006 x=_x; 1007 y=_y; 1008 } 1009 }; 1010 1011 %} 1012 </pre></div> 1013 1014 <p> 1015 can be used in Scilab like this: 1016 </p> 1017 1018 <div class="targetlang"><pre> 1019 --> p1 = Point_new(3, 5); 1020 --> p2 = Point_new(1, 2); 1021 --> p1.distance(p2) 1022 ans = 1023 1024 3.6056 1025 1026 --> delete_Point(p1); 1027 --> delete_Point(p2); 1028 </pre></div> 1029 1030 <p> 1031 Note: like structs, class pointers are mapped as described in <a href="#Scilab_wrapping_pointers">Pointers</a>. Let's give an example which shows that each class pointer type is a new type in Scilab that can be used for example (through <a href="https://help.scilab.org/docs/5.5.2/en_US/overloading.html">overloading</a>) to implement a custom print for the <tt>Point</tt> class: 1032 </p> 1033 1034 <div class="targetlang"><pre> 1035 --> function %_p_Point_p(p) 1036 --> mprintf('[%d, %d]\n', Point_x_get(p), Point_y_get(p)); 1037 --> endfunction 1038 1039 --> example_Init(); 1040 --> p = new_Point(1, 2) 1041 p = 1042 1043 [1, 2] 1044 1045 --> delete_Point(p); 1046 </pre></div> 1047 1048 <H3><a name="Scilab_wrapping_cpp_inheritance">36.3.9 C++ inheritance</a></H3> 1049 1050 1051 <p> 1052 Inheritance is supported. SWIG knows the inheritance relationship between classes. 1053 </p> 1054 1055 <p> 1056 A function is only generated for the class in which it is actually declared. 1057 But if one of its parameters is a class, any instance of a derived class is accepted as the argument. 1058 </p> 1059 1060 <p> 1061 This mechanism also applies for accessor functions: they are generated only in the class in which they are defined. 1062 But any instance of a derived class can be used as the argument to these accessor functions. 1063 </p> 1064 1065 <p> 1066 For example, let's take a base class <tt>Shape</tt> and two derived classes <tt>Circle</tt> and <tt>Square</tt>: 1067 </p> 1068 1069 <div class="code"><pre> 1070 %module example 1071 1072 %inline %{ 1073 1074 class Shape { 1075 public: 1076 double x, y; 1077 void set_location(double _x, double _y) { x = _x; y = _y; } 1078 virtual double get_perimeter() { return 0; }; 1079 }; 1080 1081 class Circle : public Shape { 1082 public: 1083 int radius; 1084 Circle(int _radius): radius(_radius) {}; 1085 virtual double get_perimeter() { return 6.28 * radius; } 1086 }; 1087 1088 class Square : public Shape { 1089 public: 1090 int size; 1091 Square(int _size): size(_size) {}; 1092 virtual double get_perimeter() { return 4 * size; } 1093 }; 1094 1095 %} 1096 </pre></div> 1097 1098 <p> 1099 To set the location of the <tt>Circle</tt>, we have to use the function <tt>set_location()</tt> of the parent <tt>Shape</tt>. 1100 But we can use either use the <tt>get_perimeter()</tt> function of the parent class or the derived class: 1101 </p> 1102 1103 <div class="targetlang"><pre> 1104 --> c = new_Circle(3); 1105 1106 --> Shape_set_location(c, 2, 3); 1107 --> Shape_x_get(c) 1108 ans = 1109 1110 2. 1111 1112 --> Circle_get_perimeter(c) 1113 ans = 1114 1115 18.84 1116 1117 --> Shape_get_perimeter(c) 1118 ans = 1119 1120 18.84 1121 </pre></div> 1122 1123 <H3><a name="Scilab_wrapping_cpp_overloading">36.3.10 C++ overloading</a></H3> 1124 1125 1126 <p> 1127 As explained in <a href="SWIGPlus.html#SWIGPlus_overloaded_methods">Overloaded functions and methods</a> SWIG provides support for overloaded functions and constructors. 1128 </p> 1129 1130 <p>As SWIG knows pointer types, the overloading works also with pointer types, here is an example with a function <tt>magnify</tt> overloaded for the previous classes <tt>Shape</tt> and <tt>Circle</tt>: 1131 </p> 1132 1133 <div class="code"><pre> 1134 %module example 1135 1136 void magnify(Square *square, double factor) { 1137 square->size *= factor; 1138 }; 1139 1140 void magnify(Circle *circle, double factor) { 1141 square->radius *= factor; 1142 }; 1143 </pre></div> 1144 1145 <div class="targetlang"><pre> 1146 --> example_Init(); 1147 --> c = new_Circle(3); 1148 --> s = new_Square(2); 1149 1150 --> magnify(c, 10); 1151 --> Circle_get_radius(c) 1152 ans = 1153 1154 30; 1155 --> magnify(s, 10); 1156 --> Square_get_size(s) 1157 ans = 1158 1159 20; 1160 </pre></div> 1161 1162 1163 <H3><a name="Scilab_wrapping_pointers_references_values_arrays">36.3.11 Pointers, references, values, and arrays</a></H3> 1164 1165 1166 <p> 1167 In C++ objects can be passed by value, pointer, reference, or by an array: 1168 </p> 1169 <div class="code"><pre> 1170 %module example 1171 1172 %{ 1173 #include <sciprint.h> 1174 %} 1175 1176 %inline %{ 1177 1178 class Foo { 1179 public: 1180 Foo(int _x) : x(_x) {} 1181 int x; 1182 }; 1183 1184 void spam1(Foo *f) { sciprint("%d\n", f->x); } // Pass by pointer 1185 void spam2(Foo &f) { sciprint("%d\n", f.x); } // Pass by reference 1186 void spam3(Foo f) { sciprint("%d\n", f.x); } // Pass by value 1187 void spam4(Foo f[]) { sciprint("%d\n", f[0].x); } // Array of objects 1188 1189 %} 1190 </pre></div> 1191 <p> 1192 1193 In SWIG, there is no real distinction between these. 1194 So in Scilab, it is perfectly legal to do this: 1195 </p> 1196 <div class="targetlang"><pre> 1197 --> f = new_Foo() 1198 --> spam1(f) 1199 3 1200 --> spam2(f) 1201 3 1202 --> spam3(f) 1203 3 1204 --> spam4(f) 1205 3 1206 </pre></div> 1207 1208 <p> 1209 Similar behaviour occurs for return values. For example, if you had functions like this: 1210 </p> 1211 <div class="code"><pre> 1212 Foo *spam5(); 1213 Foo &spam6(); 1214 Foo spam7(); 1215 </pre></div> 1216 <p> 1217 All these functions will return a pointer to an instance of <tt>Foo</tt>. 1218 As the function <tt>spam7</tt> returns a value, new instance of <tt>Foo</tt> has to be allocated, and a pointer on this instance is returned. 1219 </p> 1220 1221 <H3><a name="Scilab_wrapping_cpp_templates">36.3.12 C++ templates</a></H3> 1222 1223 1224 <p> 1225 As in other languages, function and class templates are supported in SWIG Scilab. 1226 </p> 1227 1228 <p> 1229 You have to tell SWIG to create wrappers for a particular template instantiation. The <tt>%template</tt> directive is used for this purpose. 1230 For example: 1231 </p> 1232 1233 <div class="code"><pre> 1234 %module example 1235 1236 template<class T1, class T2, class T3> 1237 struct triplet { 1238 T1 first; 1239 T2 second; 1240 T3 third; 1241 triplet(const T1& a, const T2& b, const T3& c) { 1242 third = a; second = b; third = c; 1243 } 1244 }; 1245 1246 %template(IntTriplet) triplet<int, int, int>; 1247 </pre></div> 1248 1249 <p> 1250 Then in Scilab: 1251 </p> 1252 1253 <div class="targetlang"> 1254 <pre> 1255 --> t = new_IntTriplet(3, 4, 1); 1256 1257 --> IntTriplet_first_get(t) 1258 ans = 1259 1260 3. 1261 1262 --> IntTriplet_second_get(t) 1263 ans = 1264 1265 4. 1266 1267 --> IntTriplet_third_get(t) 1268 ans = 1269 1270 1. 1271 1272 --> delete_IntTriplet(t); 1273 </pre> 1274 </div> 1275 1276 <p> 1277 More details on template support can be found in the <a href="SWIGPlus.html#SWIGPlus_nn30">templates</a> documentation. 1278 </p> 1279 1280 <H3><a name="Scilab_wrapping_cpp_operators">36.3.13 C++ operators</a></H3> 1281 1282 1283 <p> 1284 C++ operators are partially supported. 1285 Operator overloading exists in Scilab, but a C++ operator is not (in this version) wrapped by SWIG as a Scilab operator, but as a function. 1286 It is not automatic, you have to rename each operator (with the instruction <tt>%rename</tt>) with the suitable wrapper name. 1287 </p> 1288 1289 <p> 1290 Let's see it with an example of class with two operators <tt>+</tt> and <tt>double()</tt>: 1291 </p> 1292 1293 <div class="code"><pre> 1294 %module example 1295 1296 %rename(plus) operator +; 1297 %rename(toDouble) operator double(); 1298 1299 %inline %{ 1300 1301 class Complex { 1302 public: 1303 Complex(double re, double im) : real(re), imag(im) {}; 1304 1305 Complex operator+(const Complex& other) { 1306 double result_real = real + other.real; 1307 double result_imaginary = imag + other.imag; 1308 return Complex(result_real, result_imaginary); 1309 } 1310 operator double() { return real; } 1311 private: 1312 double real; 1313 double imag; 1314 }; 1315 1316 %} 1317 </pre></div> 1318 1319 <br/> 1320 1321 <div class="targetlang"><pre> 1322 --> c1 = new_Complex(3, 7); 1323 1324 --> c2 = Complex_plus(c, new_Complex(1, 1)); 1325 1326 --> Complex_toDouble(c2) 1327 ans = 1328 1329 4. 1330 </pre></div> 1331 1332 1333 <H3><a name="Scilab_wrapping_cpp_namespaces">36.3.14 C++ namespaces</a></H3> 1334 1335 1336 <p> 1337 SWIG is aware of C++ namespaces, but does not use it for wrappers. 1338 The module is not broken into submodules, nor do namespace appear in functions names. 1339 All the namespaces are all flattened in the module. 1340 For example with one namespace <tt>Foo</tt>: 1341 </p> 1342 1343 <div class="code"> 1344 <pre> 1345 %module example 1346 1347 %inline %{ 1348 1349 namespace foo { 1350 int fact(int n) { 1351 if (n > 1) 1352 return n * fact(n-1); 1353 else 1354 return 1; 1355 } 1356 1357 struct Vector { 1358 double x, y, z; 1359 }; 1360 }; 1361 1362 %} 1363 1364 </pre> 1365 </div> 1366 1367 <p> 1368 In Scilab, there is no need to the specify the <tt>Foo</tt> namespace: 1369 </p> 1370 1371 <div class="targetlang"> 1372 <pre> 1373 --> fact(3) 1374 ans = 1375 1376 6. 1377 1378 --> v = new_Vector(); 1379 --> Vector_x_set(v, 3.4); 1380 --> Vector_y_get(v) 1381 ans = 1382 1383 0. 1384 </pre> 1385 </div> 1386 1387 <p> 1388 If your program has more than one namespace, name conflicts can be resolved using <tt>%rename</tt>. 1389 For example: 1390 </p> 1391 1392 <div class="code"> 1393 <pre> 1394 %rename(Bar_spam) Bar::spam; 1395 1396 namespace Foo { 1397 int spam(); 1398 } 1399 1400 namespace Bar { 1401 int spam(); 1402 } 1403 </pre> 1404 </div> 1405 1406 <p> 1407 Note: the <a href="SWIGPlus.html#SWIGPlus_nspace">nspace</a> feature is not supported. 1408 </p> 1409 1410 1411 <H3><a name="Scilab_wrapping_cpp_exceptions">36.3.15 C++ exceptions</a></H3> 1412 1413 1414 <p> 1415 Scilab does not natively support exceptions, but has errors. 1416 When an exception is thrown, SWIG catches it, and sets a Scilab error. An error message is displayed in Scilab. 1417 For example: 1418 </p> 1419 1420 <div class="code"><pre> 1421 %module example 1422 1423 %inline %{ 1424 void throw_exception() throw(char const *) { 1425 throw "Bye world !"; 1426 } 1427 %} 1428 </pre></div> 1429 1430 <br/> 1431 1432 <div class="targetlang"><pre> 1433 -->throw_exception() 1434 !--error 999 1435 SWIG/Scilab: Exception (char const *) occurred: Bye world ! 1436 </pre></div> 1437 1438 <p> 1439 Scilab has a <tt>try-catch</tt> mechanism (and a similar instruction <tt>execstr()</tt>) to handle exceptions. 1440 It can be used with the <tt>lasterror()</tt> function as following: 1441 </p> 1442 1443 <div class="targetlang"><pre> 1444 --> execstr('throw_exception()', 'errcatch'); 1445 ans = 1446 1447 999. 1448 1449 --> lasterror() 1450 ans = 1451 1452 SWIG/Scilab: Exception (char const *) occurred: Bye world ! 1453 </pre></div> 1454 1455 <p> 1456 If the function has a <tt>throw</tt> exception specification, SWIG can automatically map the exception type and set an appropriate Scilab error message. 1457 It works for a few primitive types, and also for STL exceptions (the library <tt>std_except.i</tt> has to be included to get the STL exception support): 1458 </p> 1459 1460 <div class="code"><pre> 1461 %module example 1462 1463 %include <std_except.i> 1464 1465 %inline %{ 1466 void throw_int() throw(int) { 1467 throw 12; 1468 } 1469 1470 void throw_stl_invalid_arg(int i) throw(std::invalid_argument) { 1471 if (i < 0) 1472 throw std::invalid_argument("argument is negative."); 1473 } 1474 %} 1475 </pre></div> 1476 1477 <br/> 1478 1479 <div class="targetlang"><pre> 1480 --> throw_int(); 1481 !--error 999 1482 SWIG/Scilab: Exception (int) occurred: 12 1483 1484 -->throw_stl_invalid_arg(-1); 1485 !--error 999 1486 SWIG/Scilab: ValueError: argument is negative. 1487 </pre></div> 1488 1489 <p> 1490 More complex or custom exception types require specific exception typemaps to be implemented in order to specifically handle a thrown type. 1491 See the <a href="SWIGPlus.html#SWIGPlus">SWIG C++ documentation</a> for more details. 1492 </p> 1493 1494 <H3><a name="Scilab_wrapping_cpp_stl">36.3.16 C++ STL</a></H3> 1495 1496 1497 <p> 1498 The Standard Template Library (STL) is partially supported. See <a href="#Scilab_typemaps_stl">STL</a> for more details. 1499 </p> 1500 1501 <H2><a name="Scilab_typemaps">36.4 Type mappings and libraries</a></H2> 1502 1503 1504 <H3><a name="Scilab_typemaps_primitive_types">36.4.1 Default primitive type mappings</a></H3> 1505 1506 1507 <p> 1508 The following table provides the equivalent Scilab type for C/C++ primitive types. 1509 </p> 1510 1511 <div class="table"> 1512 <table border="1" summary="Scilab default primitive type mappings"> 1513 <tr> 1514 <td><b>C/C++ type</b></td> 1515 <td><b>Scilab type</b></td> 1516 </tr> 1517 <tr><td>bool</td><td>boolean</td></tr> 1518 <tr><td>char</td><td>string</td></tr> 1519 <tr><td>signed char</td><td>double or int8</td></tr> 1520 <tr><td>unsigned char</td><td>double or uint8</td></tr> 1521 <tr><td>short</td><td>double or int16</td></tr> 1522 <tr><td>unsigned short</td><td>double or uint16</td></tr> 1523 <tr><td>int</td><td>double or int32</td></tr> 1524 <tr><td>unsigned int</td><td>double or uint32</td></tr> 1525 <tr><td>long</td><td>double or int32</td></tr> 1526 <tr><td>unsigned long</td><td>double or uint32</td></tr> 1527 <tr><td>signed long long</td><td>not supported in Scilab 5.x</td></tr> 1528 <tr><td>unsigned long long</td><td>not supported in Scilab 5.x</td></tr> 1529 <tr><td>float</td><td>double</td></tr> 1530 <tr><td>double</td><td>double</td></tr> 1531 <tr><td>char * or char[]</td><td>string</td></tr> 1532 </table> 1533 </div> 1534 1535 <p> 1536 Notes: 1537 </p> 1538 <ul> 1539 <li>In Scilab the <tt>double</tt> type is far more used than any integer type. 1540 This is why integer values (<tt>int32</tt>, <tt>uint32</tt>, ...) are automatically converted to Scilab <tt>double</tt> values when marshalled from C into Scilab. 1541 Additionally on input to a C function, Scilab <tt>double</tt> values are converted into the related integer type. 1542 </li> 1543 <li> 1544 When an integer is expected, if the input is a double, the value must be an integer, i.e. it must not have any decimal part, otherwise a SWIG value error occurs. 1545 </li> 1546 <li> 1547 In SWIG for Scilab 5.x, the <tt>long long</tt> type is not supported, since Scilab 5.x does not have a 64-bit integer type. 1548 The default behaviour is for SWIG to generate code that will give a runtime error if <tt>long long</tt> type arguments are used from Scilab. 1549 </li> 1550 </ul> 1551 1552 1553 1554 1555 <H3><a name="Scilab_typemaps_arrays">36.4.2 Arrays</a></H3> 1556 1557 1558 <p> 1559 Typemaps are available by default for arrays. Primitive type arrays are automatically converted to/from Scilab matrices. 1560 Typemaps are also provided to handle members of a struct or class that are arrays. 1561 </p> 1562 1563 <p> 1564 In input, the matrix is usually one-dimensional (it can be either a row or column vector). But it can also be a two-dimensional matrix. 1565 Warning: in Scilab, the values are column-major ordered, unlike in C, which is row-major ordered. 1566 </p> 1567 1568 <p> 1569 The type mappings used for arrays is the same for primitive types, described <a href="#Scilab_typemaps_primitive_types">earlier</a>. 1570 This means that, if needed, a Scilab <tt>double</tt> vector is converted in input into the related C integer array 1571 and this C integer array is automatically converted on output into a Scilab <tt>double</tt> vector. 1572 Note that unlike scalars, no control is done for arrays when a <tt>double</tt> is converted into an integer. 1573 </p> 1574 1575 <p> 1576 The following example illustrates all this:</p> 1577 1578 <div class="code"><pre> 1579 %module example 1580 1581 %#include <stdio.h> 1582 1583 %inline %{ 1584 1585 void printArray(int values[], int len) { 1586 int i = 0; 1587 for (i = 0; i < len; i++) { 1588 printf("%s %d %s", i==0?"[":"", values[i], i==len-1?"]\n":""); 1589 } 1590 } 1591 %} 1592 </pre></div> 1593 1594 <br/> 1595 1596 <div class="targetlang"><pre> 1597 --> printArray([0 1 2 3], 4) 1598 [ 0 1 2 3 ] 1599 1600 --> printArray([0.2; -1.8; 2; 3.7], 4) 1601 [ 0 -1 2 3 ] 1602 1603 --> printArray([0 1; 2 3], 4) 1604 [ 0 2 1 3 ] 1605 1606 --> printArray([0; 1; 2; 3], 4) 1607 [ 0 1 2 3 ] 1608 </pre></div> 1609 1610 <H3><a name="Scilab_typemaps_pointer-to-pointers">36.4.3 Pointer-to-pointers</a></H3> 1611 1612 1613 <p> 1614 There are no specific typemaps for pointer-to-pointers, they are mapped as pointers in Scilab. 1615 </p> 1616 1617 <p> 1618 Pointer-to-pointers are sometimes used to implement matrices in C. The following is an example of this: 1619 </p> 1620 1621 1622 <div class="code"><pre> 1623 %module example 1624 %inline %{ 1625 1626 // Returns the matrix [1 2; 3 4]; 1627 double **create_matrix() { 1628 double **M; 1629 int i; 1630 M = (double **) malloc(2 * sizeof(double *)); 1631 for (i = 0; i < 2; i++) { 1632 M[i] = (double *) malloc(2 * sizeof(double)); 1633 M[i][0] = 2 * i + 1; 1634 M[i][1] = 2 * i + 2; 1635 } 1636 return M; 1637 } 1638 1639 // Gets the item M(i, j) value 1640 double get_matrix(double **M, int i, int j) { 1641 return M[i][j]; 1642 } 1643 1644 // Sets the item M(i, j) value to be val 1645 void set_matrix(double **M, int i, int j, double val) { 1646 M[i][j] = val; 1647 } 1648 1649 // Prints a matrix (2, 2) to console 1650 void print_matrix(double **M, int nbRows, int nbCols) { 1651 int i, j; 1652 for (i = 0; i < 2; i++) { 1653 for (j = 0; j < 2; j++) { 1654 printf("%3g ", M[i][j]); 1655 } 1656 printf("\n"); 1657 } 1658 } 1659 1660 %} 1661 </pre></div> 1662 1663 <p> 1664 These functions are used like this in Scilab: 1665 </p> 1666 1667 <div class="targetlang"><pre> 1668 --> m = create_matrix(); 1669 1670 --> print_matrix(m); 1671 1. 2. 1672 3. 4. 1673 1674 --> set_matrix(m, 1, 1, 5.); 1675 1676 --> get_matrix(m, 1, 1) 1677 ans = 1678 1679 5. 1680 </pre></div> 1681 1682 1683 <H3><a name="Scilab_typemaps_matrices">36.4.4 Matrices</a></H3> 1684 1685 1686 <p> 1687 The <tt>matrix.i</tt> library provides a set of typemaps which can be useful when working with one-dimensional and two-dimensional matrices. 1688 </p> 1689 1690 <p> 1691 In order to use this library, just include it in the interface file: 1692 </p> 1693 1694 <div class="code"><pre> 1695 %include <matrix.i> 1696 </pre></div> 1697 1698 1699 <p> 1700 Several typemaps are available for the common Scilab matrix types: 1701 </p> 1702 <ul> 1703 <li><tt>double</tt></li> 1704 <li><tt>int</tt></li> 1705 <li><tt>char *</tt></li> 1706 <li><tt>bool</tt></li> 1707 </ul> 1708 1709 <p> 1710 For example: for a matrix of <tt>int</tt>, we have the typemaps, for input: 1711 </p> 1712 <ul> 1713 <li><tt>(int *IN, int IN_ROWCOUNT, int IN_COLCOUNT)</tt></li> 1714 <li><tt>(int IN_ROWCOUNT, int IN_COLCOUNT, int *IN)</tt></li> 1715 <li><tt>(int *IN, int IN_SIZE)</tt></li> 1716 <li><tt>(int IN_SIZE, int *IN)</tt></li> 1717 </ul> 1718 1719 <p> 1720 and output: 1721 </p> 1722 <ul> 1723 <li><tt>(int **OUT, int *OUT_ROWCOUNT, int *OUT_COLCOUNT)</tt></li> 1724 <li><tt>(int *OUT_ROWCOUNT, int *OUT_COLCOUNT, int **OUT)</tt></li> 1725 <li><tt>(int **OUT, int *OUT_SIZE)</tt></li> 1726 <li><tt>(int *OUT_SIZE, int **OUT)</tt></li> 1727 </ul> 1728 1729 <p> 1730 They marshall a Scilab matrix type into the appropriate 2 or 3 C parameters. 1731 The following is an example using the typemaps in this library: 1732 </p> 1733 1734 <div class="code"><pre> 1735 %module example 1736 1737 %include <matrix.i> 1738 1739 %apply (int *IN, int IN_ROWCOUNT, int IN_COLCOUNT) { (int *matrix, int matrixNbRow, int matrixNbCol) }; 1740 %apply (int **OUT, int *OUT_ROWCOUNT, int *OUT_COLCOUNT) { (int **outMatrix, int *outMatrixNbRow, int *outMatrixNbCol) }; 1741 1742 %inline %{ 1743 1744 void absolute(int *matrix, int matrixNbRow, int matrixNbCol, 1745 int **outMatrix, int *outMatrixNbRow, int *outMatrixNbCol) { 1746 int i, j; 1747 *outMatrixNbRow = matrixNbRow; 1748 *outMatrixNbCol = matrixNbCol; 1749 *outMatrix = malloc(matrixNbRow * matrixNbCol * sizeof(int)); 1750 for (i=0; i < matrixNbRow * matrixNbCol; i++) { 1751 (*outMatrix)[i] = matrix[i] > 0 ? matrix[i]:-matrix[i]; 1752 } 1753 } 1754 1755 %} 1756 </pre></div> 1757 1758 <br/> 1759 1760 <div class="targetlang"><pre> 1761 --> absolute([-0 1 -2; 3 4 -5]) 1762 ans = 1763 1764 0. 1. 2. 1765 3. 4. 5. 1766 </pre></div> 1767 1768 <p> 1769 The remarks made earlier for arrays also apply here: 1770 </p> 1771 <ul> 1772 <li>The values of matrices in Scilab are column-major orderered, </li> 1773 <li>There is no control while converting <tt>double</tt> values to integers, <tt>double</tt> values are truncated without any checking or warning.</li> 1774 </ul> 1775 1776 <H3><a name="Scilab_typemaps_stl">36.4.5 STL</a></H3> 1777 1778 1779 <p> 1780 The STL library wraps some containers defined in the STL (Standard Template Library), so that they can be manipulated in Scilab. 1781 This library also provides the appropriate typemaps to use the containers in functions and variables. 1782 </p> 1783 1784 <p> 1785 The list of wrapped sequence containers are: 1786 </p> 1787 <ul> 1788 <li><tt>std::vector</tt></li> 1789 <li><tt>std::list</tt></li> 1790 <li><tt>std::deque</tt></li> 1791 </ul> 1792 1793 <p> 1794 And associative containers are: 1795 </p> 1796 <ul> 1797 <li><tt>std::set</tt></li> 1798 <li><tt>std::multiset</tt></li> 1799 </ul> 1800 1801 <p> 1802 Typemaps are available for the following container types: 1803 </p> 1804 1805 <ul> 1806 <li><tt>double</tt></li> 1807 <li><tt>float</tt></li> 1808 <li><tt>int</tt></li> 1809 <li><tt>string</tt></li> 1810 <li><tt>bool</tt></li> 1811 <li><tt>pointer</tt></li> 1812 </ul> 1813 1814 <p> 1815 Containers of other item types are not supported. Using them does not break compilation, but provokes a runtime error. 1816 Containers of enum are not supported yet. 1817 </p> 1818 1819 <p> 1820 In order to use the STL, the library must first be included in the SWIG interface file: 1821 </p> 1822 1823 <div class="code"><pre> 1824 %include <stl.i> 1825 </pre/></div> 1826 1827 <p>Then for each container used, the appropriate template must be instantiated, in the <tt>std</tt> namespace: 1828 <div class="code"><pre> 1829 namespace std { 1830 %template(IntVector) vector<int>; 1831 %template(DoubleVector) vector<double>; 1832 } 1833 </pre></div> 1834 1835 <p> 1836 Additionally, the module initialization function has to be executed first in Scilab, so that all the types are known to Scilab. 1837 See the <a href="#Scilab_module_initialization">Module initialization</a> section for more details. 1838 </p> 1839 1840 1841 <p> 1842 Because in Scilab matrices exist for basic types only, a sequence container of pointers is mapped to a Scilab list. 1843 For other item types (double, int, string...) the sequence container is mapped to a Scilab matrix. 1844 </p> 1845 1846 <p> 1847 The first example below shows how to create a vector (of <tt>int</tt>) in Scilab, add some values to the vector and pass it as an argument of a function. 1848 It also shows, thanks to the typemaps, that we can also pass a Scilab matrix of values directly into the function: 1849 </p> 1850 1851 <div class="code"><pre> 1852 %module example 1853 1854 %include <stl.i> 1855 1856 namespace std { 1857 %template(IntVector) vector<int>; 1858 } 1859 1860 %{ 1861 #include <numeric> 1862 %} 1863 1864 %inline %{ 1865 1866 double average(std::vector<int> v) { 1867 return std::accumulate(v.begin(), v.end(), 0.0) / v.size(); 1868 } 1869 1870 %} 1871 </pre></div> 1872 1873 <br/> 1874 1875 <div class="targetlang"><pre> 1876 --> example_Init(); 1877 1878 --> v = new_IntVector(); 1879 1880 --> for i = 1:4 1881 --> IntVector_push_back(v, i); 1882 --> end; 1883 1884 --> average(v) 1885 ans = 1886 1887 2.5 1888 1889 --> average([0 1 2 3]) 1890 ans = 1891 1892 2.5 1893 1894 --> delete_IntVector(); 1895 </pre></div> 1896 1897 1898 <p> 1899 In the second example, a set of struct (<tt>Person</tt>) is wrapped. 1900 A function performs a search in this set, and returns a subset. As one can see, the result in Scilab is a list of pointers: 1901 </p> 1902 1903 <div class="code"><pre> 1904 %module example 1905 1906 %include <stl.i> 1907 1908 %{ 1909 #include <string> 1910 %} 1911 1912 %inline %{ 1913 1914 struct Person { 1915 Person(std::string _name, int _age) : name(_name), age(_age) {}; 1916 std::string name; 1917 int age; 1918 }; 1919 typedef Person * PersonPtr; 1920 1921 %} 1922 1923 namespace std { 1924 %template(PersonPtrSet) set<PersonPtr>; 1925 } 1926 1927 %inline %{ 1928 1929 std::set<PersonPtr> findPersonsByAge(std::set<PersonPtr> persons, int minAge, int maxAge) { 1930 std::set<PersonPtr> foundPersons; 1931 for (std::set<PersonPtr>::iterator it = persons.begin(); it != persons.end(); it++) { 1932 if (((*it)->age >= minAge) && ((*it)->age <= maxAge)) { 1933 foundPersons.insert(*it); 1934 } 1935 } 1936 return foundPersons; 1937 } 1938 1939 %} 1940 </pre></div> 1941 1942 <br/> 1943 1944 <div class="targetlang"><pre> 1945 --> example_Init(); 1946 1947 --> joe = new_Person("Joe", 25); 1948 --> susan = new_Person("Susan", 32); 1949 --> bill = new_Person("Bill", 50); 1950 1951 --> p = new_PersonPtrSet(); 1952 --> PersonPtrSet_insert(p, susan); 1953 --> PersonPtrSet_insert(p, joe); 1954 --> PersonPtrSet_insert(p, bill); 1955 1956 --> l = findPersonsByAge(p, 20, 40); 1957 1958 --> size(l) 1959 ans = 1960 1961 2. 1962 1963 --> Person_name_get(l(1)) 1964 ans = 1965 1966 Susan 1967 1968 --> Person_name_get(l(2)) 1969 ans = 1970 1971 Joe 1972 1973 --> delete_PersonPtrSet(p); 1974 </pre></div> 1975 1976 <H2><a name="Scilab_module_initialization">36.5 Module initialization</a></H2> 1977 1978 1979 <p> 1980 The wrapped module contains an initialization function to: 1981 </p> 1982 <ul> 1983 <li>initialize the SWIG runtime, needed for pointer type tracking or when working with the STL</li> 1984 <li>initialize the module constants and enumerations declared with <tt>%scilabconst()</tt></li> 1985 </ul> 1986 1987 <p> 1988 This initialization function should be executed at the start of a script, before the wrapped library has to be used. 1989 </p> 1990 1991 <p> 1992 The function has the name of the module suffixed by <tt>_Init</tt>. 1993 For example, to initialize the module <tt>example</tt>: 1994 </p> 1995 1996 <div class="targetlang"><pre> 1997 --> example_Init(); 1998 </pre></div> 1999 2000 <H2><a name="Scilab_building_modes">36.6 Building modes</a></H2> 2001 2002 2003 <p> 2004 The mechanism to load an external module in Scilab is called <i>Dynamic Link</i> and works with dynamic modules (or shared libraries, <tt>.so</tt> files). 2005 </p> 2006 2007 <p> 2008 To produce a dynamic module, when generating the wrapper, there are two possibilities, or build modes: 2009 </p> 2010 <ul> 2011 <li>the <tt>nobuilder</tt> mode, this is the default mode in SWIG. The user is responsible of the build. 2012 <li>the <tt>builder</tt> mode. In this mode, Scilab is responsible of building. 2013 </ul> 2014 2015 <H3><a name="Scilab_building_modes_nobuilder_mode">36.6.1 No-builder mode</a></H3> 2016 2017 2018 <p> 2019 In this mode, used by default, SWIG generates the wrapper sources, which have to be manually compiled and linked. 2020 A loader script <tt>loader.sce</tt> is also produced, this one is executed further in Scilab to load the module. 2021 </p> 2022 2023 <p> 2024 This mode is the best option to use when you have to integrate the module build into a larger build process. 2025 </p> 2026 2027 2028 <H3><a name="Scilab_building_modes_builder_mode">36.6.2 Builder mode</a></H3> 2029 2030 2031 <p> 2032 In this mode, in addition to the wrapper sources, SWIG produces a builder Scilab script (<tt>builder.sce</tt>), which is executed in Scilab to build the module. 2033 In a few words, the Scilab <tt>ilib_build()</tt> command is used, which produces the shared library file, and the loader script <tt>loader.sce</tt> (and also a cleaner script <tt>cleaner.sce</tt>). 2034 </p> 2035 2036 <p> 2037 An advantage of this mode is that it hides all the complexity of the build and other platform issues. 2038 Also it allows the module to conform to a Scilab external module convention which is that an external module should be simply built by calling a builder script. 2039 </p> 2040 2041 <p> 2042 The builder mode is activated with the <tt>-builder</tt> SWIG option. 2043 In this mode, the following SWIG options may be used to setup the build: 2044 </p> 2045 2046 <ul> 2047 <li><tt><b>-buildersources</b></tt>: to add sources to the build (several files must be separated by a comma)</li> 2048 <li><tt><b>-buildercflags</b></tt>: to add flags to the builder compiler flags, for example to set library dependencies include paths</li> 2049 <li><tt><b>-builderldflags</b></tt>: to add flags to the linker flags, for example to set library dependency names and paths</li> 2050 </ul> 2051 2052 <p> 2053 Let's give an example how to build a module <tt>example</tt>, composed of two sources, and using a library dependency: 2054 </p> 2055 <ul> 2056 <li>the sources are <tt>baa1.c</tt> and <tt>baa2.c</tt> (and are stored in the current directory)</li> 2057 <li>the library is <tt>libfoo</tt> in <tt>/opt/foo</tt> (headers stored in <tt>/opt/foo/include</tt>, and shared library in <tt>/opt/foo/lib</tt>)</li> 2058 </ul> 2059 2060 <p> 2061 The command is: 2062 </p> 2063 2064 <div class="shell"><pre> 2065 $ swig -scilab -builder -buildercflags -I/opt/foo/include -builderldflags "-L/opt/foo/lib -lfoo" -buildersources baa1.cxx, baa2.cxx example.i 2066 </pre></div> 2067 2068 <H2><a name="Scilab_generated_scripts">36.7 Generated scripts</a></H2> 2069 2070 2071 <p> 2072 In this part we give some details about the generated Scilab scripts. 2073 </p> 2074 2075 <H3><a name="Scilab_generated_scripts_builder_script">36.7.1 Builder script</a></H3> 2076 2077 2078 <p> 2079 <tt>builder.sce</tt> is the name of the builder script generated by SWIG in <tt>builder</tt> mode. It contains code like this: 2080 </p> 2081 <div class="code"><pre> 2082 ilib_name = "examplelib"; 2083 files = ["example_wrap.c"]; 2084 libs = []; 2085 table = ["fact", "_wrap_fact";"Foo_set", "_wrap_Foo_set";"Foo_get", "_wrap_Foo_get";]; 2086 ilib_build(ilib_name, table, files, libs); 2087 </pre></div> 2088 2089 <p> 2090 <tt>ilib_build(lib_name, table, files, libs)</tt> is used to create shared libraries, and to generate a loader file used to dynamically load the shared library into Scilab. 2091 </p> 2092 2093 <ul> 2094 <li><tt><b>ilib_name</b></tt>: a character string, the generic name of the library without path and extension.</li> 2095 <li><tt><b>files</b></tt>: string matrix containing objects files needed for shared library creation.</li> 2096 <li><tt><b>libs</b></tt>: string matrix containing extra libraries needed for shared library creation.</li> 2097 <li><tt><b>table</b></tt>: two column string matrix containing a table of pairs of 'scilab function name', 'C function name'.</li> 2098 </ul> 2099 2100 <H3><a name="Scilab_generated_scripts_loader_script">36.7.2 Loader script</a></H3> 2101 2102 2103 <p> 2104 The loader script is used to load in Scilab all the module functions. When loaded, these functions can be used as other Scilab functions. 2105 </p> 2106 2107 <p> 2108 The loader script <tt>loader.sce</tt> contains code similar to: 2109 </p> 2110 2111 <div class="code"><pre> 2112 // ------------------------------------------------------ 2113 // generated by builder.sce: Please do not edit this file 2114 // ------------------------------------------------------ 2115 2116 libexamplelib_path = get_file_path('loader.sce'); 2117 list_functions = [ 'fact'; 2118 'Foo_set'; 2119 'Foo_get'; 2120 ]; 2121 addinter(libexamplelib_path+'/libexamplelib.so', 'libexamplelib', list_functions); 2122 // remove temp. variables on stack 2123 clear libexamplelib_path; 2124 clear list_functions; 2125 clear get_file_path; 2126 // ------------------------------------------------------ 2127 </pre></div> 2128 2129 <p> 2130 <tt>addinter(files, spname, fcts)</tt> performs dynamic linking of a compiled C interface function. 2131 </p> 2132 <ul> 2133 <li><tt><b>files</b></tt>: a character string or a vector of character strings defining the object files (containing the C interface functions) to link with.</li> 2134 <li><tt><b>spname</b></tt>: a character string. Name of interface routine entry point.</li> 2135 <li><tt><b>fcts</b></tt>: vector of character strings. The name of new Scilab function.</li> 2136 </ul> 2137 2138 2139 <H2><a name="Scilab_other_resources">36.8 Other resources</a></H2> 2140 2141 2142 <ul> 2143 <li>Example use cases can be found in the <tt>Examples/scilab</tt> directory.</li> 2144 <li>The test suite in the <tt>Examples/test-suite/scilab</tt> can be another source of useful use cases.</li> 2145 <li>The <a href="https://help.scilab.org/docs/5.5.0/en_US/api_scilab.html">Scilab API</a> is used in the generated code and is a useful reference when examining the output.</li> 2146 <li>This <a href="https://wiki.scilab.org/howto/Create%20a%20toolbox">guide</a> describes the Scilab external modules structure and files, in particular the files that are generated by SWIG for Scilab.</li> 2147 </ul> 2148