add new help pages and examples for CAPI
[scilab.git] / scilab / modules / core / help / en_US / capi / HowToCreateAndAccessAList_1.xml
1 <?xml version="1.0" encoding="UTF-8"?>
2 <refentry version="5.0-subset Scilab" xml:id="HowToCreateAndAccessAList_1"
3           xmlns="http://docbook.org/ns/docbook"
4           xmlns:xlink="http://www.w3.org/1999/xlink"
5           xmlns:xi="http://www.w3.org/2001/XInclude"
6           xmlns:svg="http://www.w3.org/2000/svg"
7           xmlns:mml="http://www.w3.org/1998/Math/MathML"
8           xmlns:html="http://www.w3.org/1999/xhtml"
9           xmlns:db="http://docbook.org/ns/docbook">
10   <refnamediv>
11     <refname>How to create and access a list</refname>
12
13     <refpurpose>How to create and access a list using the C API</refpurpose>
14   </refnamediv>
15
16   <refsection>
17     <title>Description</title>
18
19     <para>The goal is to get a [mt]list, to get some elements stored in that
20     this and to send a new [mt]list using a function written in C.</para>
21
22     <para>For this, we will wrote 2 C gateway function in which we will
23     retrieve the [mt]list, and we will create a new [mt]list.</para>
24   </refsection>
25
26   <refsection>
27     <title>The C function - access to a [mt]list</title>
28
29     <para>This example is available in example/print_list.</para>
30
31     <para>Let's initialize a mlist in Scilab.</para>
32
33     <programlisting> 
34 A = mlist(['mytype','var1','var2'],'a string',[1 2; 3 4]);
35  </programlisting>
36
37     <para>This mlist is of type 'mytype' (typeof(A)=='mytype') and it has 2
38     elements:</para>
39
40     <itemizedlist>
41       <listitem>
42         <para>A('var1') which is equal to 'a string'</para>
43       </listitem>
44
45       <listitem>
46         <para>A('var2') which is equal to [1 2; 3 4]</para>
47       </listitem>
48     </itemizedlist>
49
50     <para>We now create a C function called sci_print_list which will print
51     the elements stored in the list.</para>
52
53     <programlisting> 
54 #include &lt;stack-c.h&gt;
55 #include &lt;sciprint.h&gt;
56
57 int sci_print_list(char * fname)
58 {
59   int m_list_in, n_list_in, l_list_in;
60   int m_type,    n_type;
61   int m_var1,    n_var1,    l_var1;
62   int m_var2,    n_var2,    l_var2;
63   char ** LabelList = NULL;
64   
65   CheckRhs(1,1); // We accept only 1 parameter
66   
67   GetRhsVar(1,"m",&amp;m_list_in,&amp;n_list_in,&amp;l_list_in); // Get a mlist
68   
69   // Get the type and the name of the variables (the first element of the mlist)
70   GetListRhsVar(1,1,"S",&amp;m_type,&amp;n_type,&amp;LabelList);
71   
72   if (strcmp(LabelList[0],"mytype")!=0)
73     {
74       sciprint("error, you must ship a mlist or type mytype\n");
75       return 0;
76     }
77     
78   // Get the first variable (a string)
79   GetListRhsVar(1,2,"c",&amp;m_var1,&amp;n_var1,&amp;l_var1);
80   sciprint("var1 = %s\n",cstk(l_var1));
81   
82   // Get the second variable (a double matrix)
83   GetListRhsVar(1,3,"d",&amp;m_var2,&amp;n_var2,&amp;l_var2);
84   sciprint("var2 = [%f %f %f %f]\n",*stk(l_var2+0),
85                                     *stk(l_var2+1),
86                                     *stk(l_var2+2),
87                                     *stk(l_var2+3));
88     
89   return 0;
90 }
91  </programlisting>
92
93     <para>To be able to build and link such a C function to scilab, we need to
94     write a Scilab script which will compile this C function and then create a
95     loader script which will link the C function to a Scilab function. The C
96     file is available in the example directory. It is named
97     print_list.c.</para>
98   </refsection>
99
100   <refsection>
101     <title>The builder script</title>
102
103     <programlisting role="example"> 
104 // This is the builder.sce 
105 // must be run from this directory 
106
107 lines(0);
108
109 ilib_name  = 'lib_print_list';
110
111 files = ['print_list.c'];
112
113 libs  = [];
114
115 table =['print_list', 'sci_print_list'];
116
117 ldflags = "";
118 cflags  = "";
119 fflags  = "";
120
121 // do not modify below 
122 // ----------------------------------------------
123 ilib_build(ilib_name,table,files,libs,'Makelib',ldflags,cflags,fflags);
124   </programlisting>
125
126     <para>This file must be saved as "builder.sce".</para>
127
128     <para>This script will tell Scilab which files must be compiled (here,
129     it's print_list.c), what will be the name of the shared library (here,
130     it's lib_print_list) and which C symbol will be linked to a Scilab
131     function (here, we will link the sci_print_list C symbol to the Scilab
132     function "print_list").</para>
133
134     <para>To build this function, we just need to to:</para>
135
136     <programlisting> 
137 exec builder.sce;
138  </programlisting>
139
140     <para>Now we are able to test our new C function. First, let's load this
141     new function in scilab:</para>
142
143     <programlisting> 
144 exec loader.sce; 
145  </programlisting>
146
147     <para>The script loader.sce is normally automatically built by
148     builder.sce. Let's test our new function:</para>
149
150     <programlisting> 
151 exec builder.sce;
152 exec loader.sce;
153
154 A = mlist(['mytype','var1','var2'],'a string',[1 2; 3 4]);
155  
156 print_list(A);
157  </programlisting>
158   </refsection>
159
160   <refsection>
161     <title>The C function - creation of a [mt]list</title>
162
163     <para>This example is available in example/create_list.</para>
164
165     <para>We now write a simple example to test our new function to create a
166     [mt]list.</para>
167
168     <programlisting> 
169 A = create_list();
170
171 disp(A);
172  </programlisting>
173
174     <para>First, let's write the C function:</para>
175
176     <programlisting> 
177 #include &lt;stack-c.h&gt;
178 #include &lt;string.h&gt;
179
180 int sci_create_list(char * fname)
181 {
182   int m_list_out, n_list_out;
183   int m_var1,     n_var1,     l_var1,  l_list_var1;
184   int m_var2,     n_var2,     l_var2,  l_list_var2;
185   int m_mlist,    n_mlist,    l_mlist;
186  
187   // The labels of our mlist 
188   static const char * ListLabels [] = {"mylist","var1","var2"};
189
190   // First, we create the variables using a classical way
191   // The size of the Scilab variables
192   m_var1  = 1; n_var1  = strlen("a string")+1; // a null terminated string
193   m_var2  = 2; n_var2  = 2; // A 2x2 double matrix
194   m_mlist = 3; n_mlist = 1; // A mlist with 3 elements
195   
196   // Creation of the Scilab variables
197   // A('var1')
198   CreateVar(1, "c", &amp;m_var1,  &amp;n_var1,  &amp;l_var1);
199   // A('var2')
200   CreateVar(2, "d", &amp;m_var2,  &amp;n_var2,  &amp;l_var2);
201   // A
202   CreateVar(3, "m", &amp;m_mlist, &amp;n_mlist, &amp;l_mlist);
203   
204   // We store values in the create variables
205   // The matrix will be stored in A('var2')
206   *stk(l_var2+0) = 1;              
207   *stk(l_var2+1) = 2;              
208   *stk(l_var2+2) = 3;              
209   *stk(l_var2+3) = 4;              
210   
211   // The string will be stored in A('var1')
212   strncpy(cstk(l_var1),"a string\0",n_var1);
213   
214   m_list_out = 3; n_list_out = 1;
215   
216   // now, affect the variable  to the mlist
217   // The labels (it corresponds to A = mlist(['mylist','var1','var2'], ...
218   CreateListVarFromPtr(3, 1, "S", &amp;m_list_out, &amp;n_list_out, ListLabels);
219   // The value stored in A('var1') (it corresponds to A = ...,'a string', ...
220   CreateListVarFrom(3, 2, "c", &amp;m_var1, &amp;n_var1, &amp;l_list_var1, &amp;l_var1);
221   // The value stored in A('var2') (it corresponds to A = ...,[1 2,3 4]);
222   CreateListVarFrom(3, 3, "d", &amp;m_var2, &amp;n_var2, &amp;l_list_var2, &amp;l_var2);
223   
224   // We return only the mlist which has been created at position 3
225   LhsVar(1) = 3;
226   
227   return 0;
228 }
229  </programlisting>
230
231     <para>Some important comments related to the CreateVar(Pos,"m",&amp;m,
232     &amp;n, &amp;l) function. When called on a mlist, only the m parameter is
233     taken in account, the n parameter is not used. So, be careful:</para>
234
235     <programlisting> 
236 m_list = 3; n_list = 1;
237 CreateVar(1, "m", &amp;m_list, &amp;n_list, &amp;l_list);
238  </programlisting>
239
240     <para>creates a mlist with 3 elements but:</para>
241
242     <programlisting> 
243 m_list = 1; n_list = 3;
244 CreateVar(1, "m", &amp;m_list, &amp;n_list, &amp;l_list);
245  </programlisting>
246
247     <para>creates a mlist with only 1 element !</para>
248
249     <para>Another important thing: when we create a list element using
250     CreateListVarFrom, it is not recommended to access the created variable
251     using, for example, stk(l_list_var2) because CreateListVarFrom performs
252     type transformation on the list variables.</para>
253   </refsection>
254
255   <refsection>
256     <title>The builder script</title>
257
258     <programlisting role="example"> 
259 // This is the builder.sce 
260 // must be run from this directory 
261
262 lines(0);
263
264 ilib_name  = 'lib_create_list';
265
266 files = ['create_list.c'];
267
268 libs  = [];
269
270 table =['create_list', 'sci_create_list'];
271
272 ldflags = "";
273 cflags  = "";
274 fflags  = "";
275
276 // do not modify below 
277 // ----------------------------------------------
278 ilib_build(ilib_name,table,files,libs,'Makelib',ldflags,cflags,fflags);
279   </programlisting>
280
281     <para>This file must be saved as "builder.sce".</para>
282
283     <para>This script will tell Scilab which files must be compiled (here,
284     it's create_list.c), what will be the name of the shared library (here,
285     it's lib_create_list) and which C symbol will be linked to a Scilab
286     function (here, we will link the sci_create_list C symbol to the Scilab
287     function "create_list").</para>
288
289     <para>To build this function, we just need to to:</para>
290
291     <programlisting> 
292 exec builder.sce;
293  </programlisting>
294
295     <para>Now we are able to test our new C function. First, let's load this
296     new function in scilab:</para>
297
298     <programlisting> 
299 exec loader.sce; 
300  </programlisting>
301
302     <para>The script loader.sce is normally automatically built by
303     builder.sce. Let's test our new function:</para>
304
305     <programlisting> 
306 exec builder.sce;
307 exec loader.sce;
308
309 A = create_list();
310  
311 disp(typeof(A))
312 disp(getfield(1,A))
313 disp(A('var1'))
314 disp(A('var2'))
315  </programlisting>
316   </refsection>
317
318   <refsection>
319     <title>See Also</title>
320
321     <simplelist type="inline">
322       <member><link linkend="GetRhsVar">GetRhsVar</link></member>
323
324       <member><link linkend="GetListRhsVar">GetListRhsVar</link></member>
325
326       <member><link linkend="CreateVar">CreateVar</link></member>
327
328       <member><link
329       linkend="CreateListVarFrom">CreateListVarFrom</link></member>
330
331       <member><link
332       linkend="CreateListVarFromPtr">CreateListVarFromPtr</link></member>
333
334       <member><link linkend="LhsVar">LhsVar</link></member>
335
336       <member><link linkend="stk">stk</link></member>
337
338       <member><link linkend="ilib_build">ilib_build</link></member>
339     </simplelist>
340   </refsection>
341 </refentry>