doc: add missing -lm option to command line for compiling tut1
[comedilib.git] / doc / bindings.xml
1 <?xml version="1.0" encoding="utf-8"?>
2 <!DOCTYPE article PUBLIC "-//OASIS//DTD DocBook XML V4.4//EN"
3         "http://www.oasis-open.org/docbook/xml/4.4/docbookx.dtd" [
4 <!ENTITY % comedilib_entities SYSTEM "comedilib.ent">
5 %comedilib_entities;
6 ]>
7 <section id="languagebindings">
8         <title>Language bindings</title>
9         <para>
10     Comedilib is a C library but comes also with bindings for Python, Perl, and Ruby.
11     This enables usage of a DAQ device directly from these higher level languages.
12     </para>
13
14     <section id="pythonbindings">
15                 <title>Python bindings</title>
16                 <para>
17         Python bindings are automatically generated by SWIG. So always keep in mind that
18         for precise information the <ulink url="http://www.swig.org/Doc2.0/index.html">SWIG documentation</ulink>
19         can come in handy in addition to the &comedi; documentation.
20         </para>
21         <para>
22         The name of the module is called <filename>comedi</filename>. All the C functions, structs, and
23         constants are directly available as is. So you can refer directly to the C
24         documentation for most of the usage. Note that, as in C, the functions either return the
25         successful result or an error code.  Unlike typical Python functions,
26         no exceptions are generated on errors (excepted type-checking
27         performed by SWIG). For example, to open a &comedi; device you can write in
28         Python:
29         <programlisting>
30 import comedi
31 device = comedi.comedi_open("/dev/comedi0")
32 if device is None:
33     errno = comedi.comedi_errno()
34     print "Error (%d) %s" % (errno, comedi.comedi_strerror(errno))
35     return
36         </programlisting>
37         </para>
38         <para>
39         There are a few things to be aware of. The SWIG bindings automatically take care
40         of converting functions with output parameters to function returning multiple
41         values, if the type of the output parameter is simple. For example
42         <function>comedi_data_read</function> takes as argument a
43         <parameter class="function">lsampl_t *data</parameter> which will contain the data
44         read after the function returns. So in C it is used like this:
45         <programlisting><![CDATA[
46 lsampl_t data;
47 rc = comedi_data_read(device, subdevice, channel, range, aref, &data);
48         ]]></programlisting>
49
50         As <parameter class="function">lsampl_t</parameter> is a 32-bit
51         <parameter class="function">unsigned int</parameter>, in Python, the function is used like this:
52         <programlisting>
53 rc, data = comedi.comedi_data_read(device, subdevice, channel, range, aref)
54         </programlisting>
55         </para>
56         <para>
57         SWIG takes care of converting simple types between Python and C, but does not
58         convert more complex types such as arrays or structs. Special Python classes are
59         created for these. Moreover, &comedi; also provides a few macros. These macros
60         are available in Python as functions with similar names, but lowercase: <function>comedi.cr_pack</function>,
61         <function>comedi.cr_range</function>, etc.
62         So to create and modify a command, one can do in Python:
63         <programlisting>
64 cmd = comedi.comedi_cmd_struct()
65 comedi.comedi_get_cmd_generic_timed(device, subdevice, cmd, nchans, period_ns)
66 cmd.stop_src = comedi.TRIG_COUNT
67 cmd.stop_arg = nscans
68 # create and add the channel list
69 clist = comedi.chanlist(nchans)
70 for i, channel in range(nchans):
71     clist[i] = comedi.cr_pack(channel, range, comedi.AREF_GROUND)
72 cmd.chanlist = clist
73         </programlisting>
74         </para>
75         <para>
76         One unfortunate consequence is that the objects to represent arrays are as low-level
77         as C arrays (i.e., a pointer with an addition). They have no range checking and
78         no iterator. In addition, they have to be <function>cast</function> from the Python object to the
79         C object. So to create an instruction to call the internal trigger, you would
80         write in Python:
81         <programlisting>
82 insn = comedi.comedi_insn_struct()
83 insn.subdev = subdevice
84 insn.insn = comedi.INSN_INTTRIG
85 insn.n = 1
86 data = comedi.lsampl_array(insn.n)
87 data[0] = num
88 insn.data = data.cast()
89 rc = comedi.comedi_do_insn(device, insn)
90         </programlisting>
91         </para>
92         <para>
93         When you need to convert from a raw SWIG object to a proxy
94         object, the <function>.frompointer</function> of the Python object can be used. Also note that by default
95         when the proxy object is deleted, SWIG frees the memory associated to it. To
96         still be able to use the memory, you need to set
97         <parameter class="function">.thisown</parameter> to <parameter class="function">False</parameter>.
98         </para>
99         <para>
100         Reading (or writing) a large set of data from a &comedi; device is done via a file.
101         In C, this is done by using a file number, but in Python you need a
102         <parameter class="function">File</parameter> object.
103         You can get a <parameter class="function">File</parameter> object via
104         <function>os.fdopen</function>. For example, to read an array of input data
105         from a &comedi; device into a numpy array, one could do:
106         <programlisting>
107 fileno = comedi.comedi_fileno(device)
108 file = os.fdopen(fileno, 'r+')
109 buf = numpy.fromfile(file, dtype=numpy.uint32, count=(nscans * nchans))
110         </programlisting>
111         </para>
112         </section>
113 </section>