Merge pull request #647 from smarchetto/master

[Scilab] #552 pointer type tracking: fix doc and CHANGES
This commit is contained in:
William S Fulton 2016-04-06 21:51:03 +01:00
commit ec2c67f59b
3 changed files with 134 additions and 33 deletions

View file

@ -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 {};

View file

@ -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>
--&gt; example_Init();
--&gt; f = fopen("junk", "w");
--&gt; typeof(f)
ans =
pointer
_p_FILE
--&gt; fputs("Hello World", f);
--&gt; 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>
--&gt; f = fopen("junk", "w");
@ -817,15 +842,20 @@ SWIG comes with two pointer utility functions:
8219088.
--&gt; p = SWIG_ptr(addr);
--&gt; typeof(p)
ans =
pointer
--&gt; fputs(" World", p);
--&gt; 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>
--&gt; example_Init();
--&gt; b = new_Bar();
--&gt; typeof(b)
ans =
_p_Bar
--&gt; delete_Bar(b);
</pre></div>
<H3><a name="Scilab_wrapping_cpp_classes">39.3.8 C++ classes</a></H3>
@ -982,6 +1025,24 @@ ans =
--&gt; 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>
--&gt; function %_p_Point_p(p)
--&gt; mprintf('[%d, %d]\n', Point_x_get(p), Point_y_get(p));
--&gt; endfunction
--&gt; example_Init();
--&gt; p = new_Point(1, 2)
p =
[1, 2]
--&gt; 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>
--&gt; example_Init();
--&gt; c = new_Circle(3);
--&gt; s = new_Square(2);
--&gt; magnify(c, 10);
--&gt; Circle_get_radius(c)
ans =
30;
--&gt; magnify(s, 10);
--&gt; 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>

View file

@ -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);