Merge pull request #647 from smarchetto/master
[Scilab] #552 pointer type tracking: fix doc and CHANGES
This commit is contained in:
commit
ec2c67f59b
3 changed files with 134 additions and 33 deletions
|
|
@ -5,6 +5,11 @@ See the RELEASENOTES file for a summary of changes in each release.
|
|||
Version 3.0.9 (in progress)
|
||||
===========================
|
||||
|
||||
2016-04-06: smarchetto
|
||||
[Scilab] #552 Make Scilab runtime keep track of pointer types
|
||||
Instead of a Scilab pointer which has no type, SWIG Scilab maps a
|
||||
pointer to a structure tlist containing the pointer adress and its type.
|
||||
|
||||
2016-04-02: ahnolds
|
||||
[Python] Apply #598. Fix misleading error message when attempting to read a non-existent
|
||||
attribute. The previous cryptic error message:
|
||||
|
|
@ -13,7 +18,7 @@ Version 3.0.9 (in progress)
|
|||
AttributeError: 'Foo' object has no attribute 'bar'
|
||||
|
||||
2016-04-02: derkuci
|
||||
[Python] Patch #610 to fix #607.
|
||||
[Python] Patch #610 to fix #607.
|
||||
Fix single arguments when using python -builtin -O with %feature("compactdefaultargs")
|
||||
|
||||
2016-03-31: wsfulton
|
||||
|
|
@ -79,7 +84,7 @@ Version 3.0.9 (in progress)
|
|||
strips the symbol's suffix instead of the prefix. The example below
|
||||
will rename SomeThingCls to SomeThing and AnotherThingCls to AnotherThing:
|
||||
|
||||
%rename("%(rstrip:[Cls])s") "";
|
||||
%rename("%(rstrip:[Cls])s") "";
|
||||
|
||||
class SomeThingCls {};
|
||||
struct AnotherThingCls {};
|
||||
|
|
|
|||
|
|
@ -45,6 +45,7 @@
|
|||
<li><a href="#Scilab_wrapping_structs">Structures</a>
|
||||
<li><a href="#Scilab_wrapping_cpp_classes">C++ classes</a>
|
||||
<li><a href="#Scilab_wrapping_cpp_inheritance">C++ inheritance</a>
|
||||
<li><a href="#Scilab_wrapping_cpp_overloading">C++ overloading</a></li>
|
||||
<li><a href="#Scilab_wrapping_pointers_references_values_arrays">Pointers, references, values, and arrays</a>
|
||||
<li><a href="#Scilab_wrapping_cpp_templates">C++ templates</a>
|
||||
<li><a href="#Scilab_wrapping_cpp_operators">C++ operators</a>
|
||||
|
|
@ -752,11 +753,25 @@ typedef enum { RED, BLUE, GREEN } color;
|
|||
|
||||
|
||||
<p>
|
||||
C/C++ pointers are fully supported by SWIG. They are mapped to the Scilab pointer type ("pointer", type ID: 128).
|
||||
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.
|
||||
</p>
|
||||
<p>
|
||||
Also, thanks to the SWIG runtime which stores informations about types, pointer types are tracked between exchanges Scilab and the native code. Indeed pointer types are stored alongside the pointer adress.
|
||||
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).
|
||||
<br>
|
||||
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 acessed 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.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Given a wrapping of some of the C file functions:
|
||||
Notes:
|
||||
<ul>
|
||||
<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>
|
||||
<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 drawaback is that pointer type is lost.</li>
|
||||
</ul>
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Following is an example of the wrapping of the C <tt>FILE*</tt> pointer:
|
||||
</p>
|
||||
|
||||
<div class="code"><pre>
|
||||
|
|
@ -772,20 +787,26 @@ int fclose(FILE *);
|
|||
</pre></div>
|
||||
|
||||
<p>
|
||||
These functions can be used in a natural way from Scilab:
|
||||
These functions can be used the same way as in C from Scilab:
|
||||
</p>
|
||||
|
||||
<div class="targetlang"><pre>
|
||||
--> example_Init();
|
||||
|
||||
--> f = fopen("junk", "w");
|
||||
--> typeof(f)
|
||||
ans =
|
||||
|
||||
pointer
|
||||
_p_FILE
|
||||
|
||||
--> fputs("Hello World", f);
|
||||
--> fclose(f);
|
||||
</pre></div>
|
||||
|
||||
<p>
|
||||
Note: the type name <tt>_p_FILE</tt> which means "pointer to FILE".
|
||||
</p>
|
||||
|
||||
<p>
|
||||
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).
|
||||
</p>
|
||||
|
|
@ -794,7 +815,7 @@ The user of a pointer is responsible for freeing it or, like in the example, clo
|
|||
|
||||
|
||||
<p>
|
||||
Most of time pointer manipulation is not needed in a scripting language such as Scilab.
|
||||
As a scripting language, Scilab does not provide functions to manipulate pointers.
|
||||
However, in some cases it can be useful, such as for testing or debugging.
|
||||
</p>
|
||||
|
||||
|
|
@ -806,7 +827,11 @@ SWIG comes with two pointer utility functions:
|
|||
<li><tt>SWIG_ptr()</tt>: creates a pointer from an address value</li>
|
||||
</ul>
|
||||
|
||||
<p>Following illustrates their use on the last example:</p>
|
||||
<p>
|
||||
Note: a pointer created by <tt>SWIG_ptr()</tt> does not have any type and is mapped as a Scilab pointer.
|
||||
</p>
|
||||
|
||||
<p>Following we use the utility functions on the previous example:</p>
|
||||
|
||||
<div class="targetlang"><pre>
|
||||
--> f = fopen("junk", "w");
|
||||
|
|
@ -817,15 +842,20 @@ SWIG comes with two pointer utility functions:
|
|||
8219088.
|
||||
|
||||
--> p = SWIG_ptr(addr);
|
||||
--> typeof(p)
|
||||
ans =
|
||||
|
||||
pointer
|
||||
|
||||
--> fputs(" World", p);
|
||||
--> fclose(f);
|
||||
</pre></div>
|
||||
|
||||
<H4><a name="Scilab_wrapping_pointers_null_pointers">39.3.6.2 Null pointers</a></H4>
|
||||
|
||||
<H4><a name="Scilab_wrapping_pointers_null_pointers">39.3.6.2 Null pointers:</a></H4>
|
||||
|
||||
<p>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 <tt>SWIG_this()</tt> and <tt>SWIG_ptr()</tt>, like this:
|
||||
<p>
|
||||
Using the previous <tt>SWIG_this()</tt> and <tt>SWIG_ptr()</tt>, it is possible to create and check null pointers:
|
||||
</p>
|
||||
|
||||
<div class="targetlang"><pre>
|
||||
|
|
@ -873,7 +903,7 @@ Several functions are generated:
|
|||
<li>a destructor function <tt>delete_Foo()</tt> to release the struct pointer.</li>
|
||||
</ul>
|
||||
|
||||
<p>
|
||||
|
||||
Usage example:
|
||||
</p>
|
||||
|
||||
|
|
@ -931,6 +961,19 @@ ans =
|
|||
20.
|
||||
</pre></div>
|
||||
|
||||
<p>
|
||||
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:
|
||||
<p>
|
||||
|
||||
<div class="targetlang"><pre>
|
||||
--> example_Init();
|
||||
--> b = new_Bar();
|
||||
--> typeof(b)
|
||||
ans =
|
||||
|
||||
_p_Bar
|
||||
--> delete_Bar(b);
|
||||
</pre></div>
|
||||
|
||||
<H3><a name="Scilab_wrapping_cpp_classes">39.3.8 C++ classes</a></H3>
|
||||
|
||||
|
|
@ -982,6 +1025,24 @@ ans =
|
|||
--> delete_Point(p2);
|
||||
</pre></div>
|
||||
|
||||
<p>
|
||||
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:
|
||||
<p>
|
||||
|
||||
<div class="targetlang"><pre>
|
||||
--> function %_p_Point_p(p)
|
||||
--> mprintf('[%d, %d]\n', Point_x_get(p), Point_y_get(p));
|
||||
--> endfunction
|
||||
|
||||
--> example_Init();
|
||||
--> p = new_Point(1, 2)
|
||||
p =
|
||||
|
||||
[1, 2]
|
||||
|
||||
--> delete_Point(p);
|
||||
</pre></div>
|
||||
|
||||
<H3><a name="Scilab_wrapping_cpp_inheritance">39.3.9 C++ inheritance</a></H3>
|
||||
|
||||
|
||||
|
|
@ -1057,7 +1118,49 @@ But we can use either use the <tt>get_perimeter()</tt> function of the parent cl
|
|||
18.84
|
||||
</pre></div>
|
||||
|
||||
<H3><a name="Scilab_wrapping_pointers_references_values_arrays">39.3.10 Pointers, references, values, and arrays</a></H3>
|
||||
<H3><a name="Scilab_wrapping_cpp_overloading">39.3.10 C++ overloading</a></H3>
|
||||
|
||||
<p>
|
||||
As explained in <a href="http://www.swig.org/Doc3.0/SWIGPlus.html#SWIGPlus_overloaded_methods">6.15</a> SWIG provides support for overloaded functions and constructors.
|
||||
</p>
|
||||
|
||||
<p>As SWIG knows pointer types, the overloading works also with pointer types, here is is an example with a function <tt>magnify</tt> overloaded for the previous classes <tt>Shape</tt> and <tt>Circle</tt>:
|
||||
|
||||
<p>
|
||||
<div class="code"><pre>
|
||||
%module example
|
||||
|
||||
void magnify(Square *square, double factor) {
|
||||
square->size *= factor;
|
||||
};
|
||||
|
||||
void magnify(Circle *circle, double factor) {
|
||||
square->radius *= factor;
|
||||
};
|
||||
</pre></div>
|
||||
</p>
|
||||
|
||||
<p>
|
||||
<div class="targetlang"><pre>
|
||||
--> example_Init();
|
||||
--> c = new_Circle(3);
|
||||
--> s = new_Square(2);
|
||||
|
||||
--> magnify(c, 10);
|
||||
--> Circle_get_radius(c)
|
||||
ans =
|
||||
|
||||
30;
|
||||
--> magnify(s, 10);
|
||||
--> Square_get_size(s)
|
||||
ans =
|
||||
|
||||
20;
|
||||
</pre></div>
|
||||
</p>
|
||||
|
||||
|
||||
<H3><a name="Scilab_wrapping_pointers_references_values_arrays">39.3.11 Pointers, references, values, and arrays</a></H3>
|
||||
|
||||
|
||||
<p>
|
||||
|
|
@ -1115,7 +1218,7 @@ All these functions will return a pointer to an instance of <tt>Foo</tt>.
|
|||
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.
|
||||
</p>
|
||||
|
||||
<H3><a name="Scilab_wrapping_cpp_templates">39.3.11 C++ templates</a></H3>
|
||||
<H3><a name="Scilab_wrapping_cpp_templates">39.3.12 C++ templates</a></H3>
|
||||
|
||||
|
||||
<p>
|
||||
|
|
@ -1123,8 +1226,7 @@ As in other languages, function and class templates are supported in SWIG Scilab
|
|||
</p>
|
||||
|
||||
<p>
|
||||
You have to tell SWIG to create wrappers for a particular
|
||||
template instantiation. The <tt>%template</tt> directive is used for this purpose.
|
||||
You have to tell SWIG to create wrappers for a particular template instantiation. The <tt>%template</tt> directive is used for this purpose.
|
||||
For example:
|
||||
</p>
|
||||
|
||||
|
|
@ -1175,7 +1277,7 @@ Then in Scilab:
|
|||
More details on template support can be found in the <a href="SWIGPlus.html#SWIGPlus_nn30">templates</a> documentation.
|
||||
</p>
|
||||
|
||||
<H3><a name="Scilab_wrapping_cpp_operators">39.3.12 C++ operators</a></H3>
|
||||
<H3><a name="Scilab_wrapping_cpp_operators">39.3.13 C++ operators</a></H3>
|
||||
|
||||
|
||||
<p>
|
||||
|
|
@ -1228,7 +1330,7 @@ private:
|
|||
</pre></div>
|
||||
|
||||
|
||||
<H3><a name="Scilab_wrapping_cpp_namespaces">39.3.13 C++ namespaces</a></H3>
|
||||
<H3><a name="Scilab_wrapping_cpp_namespaces">39.3.14 C++ namespaces</a></H3>
|
||||
|
||||
|
||||
<p>
|
||||
|
|
@ -1306,7 +1408,7 @@ Note: the <a href="SWIGPlus.html#SWIGPlus_nspace">nspace</a> feature is not supp
|
|||
</p>
|
||||
|
||||
|
||||
<H3><a name="Scilab_wrapping_cpp_exceptions">39.3.14 C++ exceptions</a></H3>
|
||||
<H3><a name="Scilab_wrapping_cpp_exceptions">39.3.15 C++ exceptions</a></H3>
|
||||
|
||||
|
||||
<p>
|
||||
|
|
@ -1389,7 +1491,7 @@ More complex or custom exception types require specific exception typemaps to be
|
|||
See the <a href="SWIGPlus.html#SWIGPlus">SWIG C++ documentation</a> for more details.
|
||||
</p>
|
||||
|
||||
<H3><a name="Scilab_wrapping_cpp_stl">39.3.15 C++ STL</a></H3>
|
||||
<H3><a name="Scilab_wrapping_cpp_stl">39.3.16 C++ STL</a></H3>
|
||||
|
||||
|
||||
<p>
|
||||
|
|
@ -1448,15 +1550,9 @@ The default behaviour is for SWIG to generate code that will give a runtime erro
|
|||
</ul>
|
||||
|
||||
|
||||
<H3><a name="Scilab_typemaps_non-primitive_types">39.4.2 Default type mappings for non-primitive types</a></H3>
|
||||
|
||||
|
||||
<p>
|
||||
The default mapped type for C/C++ non-primitive types is the Scilab pointer, for example for C structs, C++ classes, etc...
|
||||
</p>
|
||||
|
||||
|
||||
<H3><a name="Scilab_typemaps_arrays">39.4.3 Arrays</a></H3>
|
||||
<H3><a name="Scilab_typemaps_arrays">39.4.2 Arrays</a></H3>
|
||||
|
||||
|
||||
<p>
|
||||
|
|
@ -1511,7 +1607,7 @@ void printArray(int values[], int len) {
|
|||
[ 0 1 2 3 ]
|
||||
</pre></div>
|
||||
|
||||
<H3><a name="Scilab_typemaps_pointer-to-pointers">39.4.4 Pointer-to-pointers</a></H3>
|
||||
<H3><a name="Scilab_typemaps_pointer-to-pointers">39.4.3 Pointer-to-pointers</a></H3>
|
||||
|
||||
|
||||
<p>
|
||||
|
|
@ -1584,7 +1680,7 @@ void print_matrix(double **M, int nbRows, int nbCols) {
|
|||
</pre></div>
|
||||
|
||||
|
||||
<H3><a name="Scilab_typemaps_matrices">39.4.5 Matrices</a></H3>
|
||||
<H3><a name="Scilab_typemaps_matrices">39.4.4 Matrices</a></H3>
|
||||
|
||||
|
||||
<p>
|
||||
|
|
@ -1677,7 +1773,7 @@ The remarks made earlier for arrays also apply here:
|
|||
<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>
|
||||
</ul>
|
||||
|
||||
<H3><a name="Scilab_typemaps_stl">39.4.6 STL</a></H3>
|
||||
<H3><a name="Scilab_typemaps_stl">39.4.5 STL</a></H3>
|
||||
|
||||
|
||||
<p>
|
||||
|
|
@ -1884,8 +1980,8 @@ ans =
|
|||
The wrapped module contains an initialization function to:
|
||||
</p>
|
||||
<ul>
|
||||
<li>initialize the SWIG runtime, which is necessary when working with the STL</li>
|
||||
<li>initialize in Scilab the module constants and enumerations declared with <tt>%scilabconst()</tt></li>
|
||||
<li>initialize the SWIG runtime, needed for pointer type tracking or when working with the STL</li>
|
||||
<li>initialize the module constants and enumerations declared with <tt>%scilabconst()</tt></li>
|
||||
</ul>
|
||||
|
||||
<p>
|
||||
|
|
|
|||
|
|
@ -245,7 +245,7 @@ SwigScilabPtrFromObject(void *pvApiCtx, int iVarOut, void *pvObj, swig_type_info
|
|||
return SWIG_ERROR;
|
||||
}
|
||||
|
||||
pstString = SWIG_TypePrettyName(descriptor);
|
||||
pstString = SWIG_TypeName(descriptor);
|
||||
sciErr = createMatrixOfStringInList(pvApiCtx, SWIG_NbInputArgument(pvApiCtx) + iVarOut, piTListAddr, 1, 1, 1, &pstString);
|
||||
if (sciErr.iErr) {
|
||||
printError(&sciErr, 0);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue