summaryrefslogtreecommitdiffstats
path: root/debian/pyrex/pyrex-0.9.9/Doc/Manual/external.html
diff options
context:
space:
mode:
Diffstat (limited to 'debian/pyrex/pyrex-0.9.9/Doc/Manual/external.html')
-rw-r--r--debian/pyrex/pyrex-0.9.9/Doc/Manual/external.html294
1 files changed, 294 insertions, 0 deletions
diff --git a/debian/pyrex/pyrex-0.9.9/Doc/Manual/external.html b/debian/pyrex/pyrex-0.9.9/Doc/Manual/external.html
new file mode 100644
index 00000000..38f19270
--- /dev/null
+++ b/debian/pyrex/pyrex-0.9.9/Doc/Manual/external.html
@@ -0,0 +1,294 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<html><head><meta content="text/html; charset=ISO-8859-1" http-equiv="content-type"><title>Interfacing with External C Code</title></head>
+<body><h1><hr style="width: 100%; height: 2px;"><a name="InterfacingWithExternal"></a>Interfacing with
+External C Code <hr width="100%"></h1><ul><li>
+<a href="#ExternDecls">External declarations</a></li><ul><li>
+<a href="#ReferencingHeaders">Referencing C header files</a></li><li>
+<a href="#StructDeclStyles">Styles of struct/union/enum
+declaration</a></li><li> <a href="#AccessingAPI">Accessing
+Python/C API routines</a></li><li><a href="#SpecialTypes">Special Types</a><span style="color: rgb(255, 0, 0);"> <span style="color: rgb(255, 102, 0);">(New in 0.9.6)</span></span></li><li><a href="#CallingConventions">Windows Calling Conventions</a><span style="color: rgb(255, 0, 0);"> <span style="color: rgb(255, 102, 0);">(New in 0.9.6)</span></span></li><li>
+<a href="#CNameSpecs">Resolving naming conflicts - C name
+specifications</a></li></ul><li><a href="#Using_Pyrex_Declarations_from_C">Using Pyrex
+declarations from C</a></li><ul><li> <a href="#PublicDecls">Public declarations</a></li></ul><ul><li><a href="#C_API_Declarations">C API declarations</a><span style="color: rgb(255, 0, 0);"> <span style="color: rgb(255, 102, 0);">(New in 0.9.6)</span></span></li><li><a href="#Multiple_public_and_api_declarations">Multiple public and API declarations</a><span style="color: rgb(255, 0, 0);"> (New in 0.9.6.3)</span></li><li><a href="#Acquiring_and_Releasing_the_GIL">Acquiring and Releasing the GIL</a><span style="color: rgb(255, 0, 0);"> <span style="color: rgb(255, 102, 0);">(New in 0.9.6)</span></span></li></ul></ul>
+One of the main uses of Pyrex is wrapping existing libraries of C code.
+This is achieved by using <a href="#ExternDecls">external
+declarations</a> to declare the C functions and variables from
+the library that you want to use. <p>You can also use <a href="#PublicDecls">public declarations</a> to make C
+functions and variables defined in a Pyrex module available to external
+C code. The need for this is expected to be less frequent, but you
+might want to do it, for example, if you are embedding Python in
+another application as a scripting language. Just as a Pyrex module can
+be used as a bridge to
+allow Python code to call C code, it can also be used to allow C code
+to
+call Python code.</p><hr style="width: 100%; height: 2px;"> <h2> <a name="ExternDecls"></a>External
+declarations</h2> By default, C functions and variables declared
+at the module level are local to the module (i.e. they have the C <b>static</b>
+storage class). They can also be declared <b>extern</b> to
+specify that they are defined elsewhere, for example: <blockquote>
+<pre>cdef extern int spam_counter</pre> <pre>cdef extern void order_spam(int tons)</pre></blockquote>
+ <h3>
+<a name="ReferencingHeaders"></a>Referencing C
+header files</h3> When you use an extern definition on its own as
+in the examples above, Pyrex includes a declaration for it in the
+generated C file. This can cause problems if the declaration doesn't
+exactly match the declaration that will be seen by other C code. If
+you're wrapping an existing C library, for example, it's important that
+the generated C code is compiled with exactly the same declarations as
+the rest of the library. <p>To achieve this, you can tell Pyrex
+that the declarations are to be found in a C header file, like this: </p>
+<blockquote> <pre>cdef extern from "spam.h":</pre> <pre>&nbsp;&nbsp;&nbsp; int spam_counter</pre><pre>&nbsp;&nbsp;&nbsp; void order_spam(int tons)</pre>
+</blockquote> The <b>cdef extern from</b> clause
+does three things: <ol><li> It directs Pyrex to place a <b>#include</b>
+statement for the named header file in the generated C code.<br> </li>
+&nbsp; <li> It prevents Pyrex from generating any C code for
+the declarations found in the associated block.<br> </li>
+&nbsp; <li> It treats all declarations within the block as
+though they
+started with <b>cdef extern</b>.</li></ol>
+It's important to understand that Pyrex does <i>not</i>
+itself read the C header file, so you still need to provide Pyrex
+versions of any declarations from it that you use. However, the Pyrex
+declarations don't always have to
+exactly match the C ones, and in some cases they shouldn't or can't. In
+particular: <ol><li> Don't use <b>const</b>.
+Pyrex doesn't know anything about const,
+so just leave it out. Most of the time this shouldn't cause any
+problem,
+although on rare occasions you might have to use a cast.<sup><a href="#Footnote1"> 1</a></sup><br> </li>
+&nbsp; <li> Leave out any platform-specific extensions to C
+declarations such as <b>__declspec()</b>.<br> </li>
+&nbsp; <li> If the header file declares a big struct and you
+only want
+to use a few members, you only need to declare the members you're
+interested in. Leaving the rest out doesn't do any harm, because the C
+compiler will use the full definition from the header file.<br> <br>
+In some cases, you might not need <i>any</i> of the
+struct's members, in
+which case you can just put <tt>pass</tt> in the body of
+the struct declaration,
+e.g.<br> <br> <tt>&nbsp; &nbsp; cdef extern
+from "foo.h":<br> &nbsp; &nbsp; &nbsp; &nbsp;
+struct spam:<br> &nbsp; &nbsp; &nbsp; &nbsp;
+&nbsp; &nbsp; pass</tt><br> <br>
+Note that you can only do this inside a <b>cdef extern from</b>
+block; struct
+declarations anywhere else must be non-empty.<br> <br> </li><li>
+If the header file uses typedef names such as <b>size_t </b>to
+refer to platform-dependent flavours of numeric types, you will need a
+corresponding <b>ctypedef</b> statement, but you don't
+need to match the type exactly, just use something of the right general
+kind (int, float, etc). For example,</li><ol><pre>ctypedef int size_t</pre></ol>
+will work okay whatever the actual size of a size_t is (provided the
+header file defines it correctly). <br> &nbsp; <li>
+If the header file uses macros to define constants, translate them into
+a dummy <b>enum</b> declaration.<br> </li>
+&nbsp; <li> If the header file defines a function using a
+macro, declare it as though it were an ordinary function, with
+appropriate argument and
+result types.</li></ol> A few more tricks and tips: <ul><li>
+If you want to include a C header because it's needed by another
+header, but don't want to use any declarations from it, put <tt><font size="+1">pass</font></tt> in the extern-from
+block:</li></ul> <ul><ul><tt>cdef extern
+from "spam.h":</tt><br><tt>&nbsp;&nbsp;&nbsp;
+pass</tt></ul></ul> <ul><li> If you want
+to include some external declarations, but don't want to specify a
+header file (because it's included by some other header that you've
+already included) you can put <tt>*</tt> in place of the
+header file name:</li></ul> <blockquote> <blockquote><tt>cdef
+extern from *:</tt> <br> <tt>&nbsp;&nbsp;&nbsp;
+...</tt></blockquote> </blockquote> <h3> <a name="StructDeclStyles"></a>Styles of struct, union
+and enum declaration</h3> There are two main ways that structs,
+unions and enums can be declared in C header files: using a tag name,
+or using a typedef. There are also some variations based on various
+combinations of these. <p>It's important to make the Pyrex
+declarations match the style used in the
+header file, so that Pyrex can emit the right sort of references to the
+type
+in the code it generates. To make this possible, Pyrex provides two
+different
+syntaxes for declaring a struct, union or enum type. The style
+introduced
+above corresponds to the use of a tag name. To get the other style, you
+prefix
+the declaration with <b>ctypedef</b>, as illustrated
+below. </p> <p>The following table shows the various
+possible styles that can be found in a header file, and the
+corresponding Pyrex declaration that you should put in the <b>cdef
+exern from </b>block. Struct declarations are used as an
+example; the same applies equally to union and enum declarations. </p>
+<p>Note that in all the cases below, you refer to the type in
+Pyrex code simply
+as <tt><font size="+1">Foo</font></tt>,
+not <tt><font size="+1">struct Foo</font></tt>.
+ </p><table cellpadding="5"> <tbody>
+<tr bgcolor="#8cbc1c" valign="top"> <td bgcolor="#8cbc1c">&nbsp;</td> <td bgcolor="#ff9933" nowrap="nowrap"><b>C code</b></td>
+<td bgcolor="#66cccc" valign="top"><b>Possibilities
+for corresponding Pyrex code</b></td> <td bgcolor="#99cc33" valign="top"><b>Comments</b></td>
+</tr> <tr bgcolor="#8cbc1c" valign="top"> <td>1</td>
+<td bgcolor="#ff9900"><tt>struct Foo {</tt> <br>
+<tt>&nbsp; ...</tt> <br> <tt>};</tt></td>
+<td bgcolor="#66cccc"><tt>cdef struct Foo:</tt>
+<br> <tt>&nbsp; ...</tt></td> <td>Pyrex
+will refer to the type as <tt>struct Foo </tt>in the
+generated C code<tt>.</tt></td> </tr> <tr bgcolor="#8cbc1c" valign="top"> <td valign="top">2</td>
+<td bgcolor="#ff9900" nowrap="nowrap"><tt>typedef
+struct {</tt> <br> <tt>&nbsp; ...</tt> <br>
+<tt>} Foo;</tt></td> <td bgcolor="#66cccc" valign="top"><tt>ctypedef struct Foo:</tt> <br>
+<tt>&nbsp; ...</tt></td> <td valign="top">Pyrex
+will refer to the type simply as <tt>Foo</tt>
+in the generated C code.</td> </tr> <tr bgcolor="#8cbc1c" valign="top"> <td rowspan="2">3</td>
+<td rowspan="2" bgcolor="#ff9900" nowrap="nowrap"><tt>typedef
+struct
+foo {</tt> <br> <tt>&nbsp; ...</tt> <br>
+<tt>} Foo;</tt></td> <td bgcolor="#66cccc" nowrap="nowrap" valign="top"><tt>cdef struct
+foo:</tt> <br> <tt>&nbsp; ...</tt> <br>
+<tt>ctypedef foo Foo #optional</tt></td> <td rowspan="2" valign="top">If the C header uses both a
+tag and a typedef with <i>different</i> names, you can use
+either form of declaration in Pyrex (although if you need to forward
+reference the type, you'll have to use
+the first form).</td> </tr> <tr> <td bgcolor="#66cccc"><tt>ctypedef struct Foo:</tt> <br>
+<tt>&nbsp; ...</tt></td> </tr> <tr bgcolor="#8cbc1c" valign="top"> <td>4</td>
+<td bgcolor="#ff9900" nowrap="nowrap"><tt>typedef
+struct Foo {</tt> <br> <tt>&nbsp; ...</tt>
+<br> <tt>} Foo;</tt></td> <td bgcolor="#66cccc" valign="top"><tt>cdef struct
+Foo:</tt> <br> <tt>&nbsp; ...</tt></td>
+<td>If the header uses the <i>same</i> name for the
+tag and the typedef, you won't be able to include a <b>ctypedef</b>
+for it -- but then, it's not
+necessary.</td> </tr> </tbody> </table> <h3>
+<a name="AccessingAPI"></a>Accessing
+Python/C API routines</h3> One particular use of the <b>cdef
+extern from</b> statement is for gaining access to routines in
+the Python/C API. For example, <blockquote> <pre>cdef extern from "Python.h":</pre>
+<pre>&nbsp;&nbsp;&nbsp; object PyString_FromStringAndSize(char *s, Py_ssize_t len)</pre></blockquote>
+will allow you to create Python strings containing
+null bytes. <h3> <a name="SpecialTypes"></a>Special
+Types</h3><p>Pyrex predefines the name <span style="font-family: monospace;">Py_ssize_t</span>
+for use with Python/C API routines. To make your extensions compatible
+with 64-bit systems, you should always use this type where it is
+specified in the documentation of Python/C API routines.</p><h3><a name="CallingConventions"></a>Windows Calling
+Conventions</h3><p>The <span style="font-family: monospace;">__stdcall</span>, <span style="font-family: monospace;">__fastcall</span> and <span style="font-family: monospace;">__cdecl</span> calling
+convention specifiers can be used in Pyrex, with the same syntax as
+used by C compilers on Windows, for example,</p><pre style="margin-left: 40px;">cdef extern int __stdcall FrobnicateWindow(long handle)<br><br>cdef void (__stdcall *callback)(void *)<br></pre>If
+__stdcall is used, the function is only considered compatible with
+other __stdcall functions of the same signature.<br><br> <hr width="100%"> <h2> <a name="CNameSpecs"></a>Resolving
+naming conflicts - C name specifications</h2> Each Pyrex module
+has a single module-level namespace for both Python
+and C names. This can be inconvenient if you want to wrap some external
+C functions and provide the Python user with Python functions of the
+same
+names. <p>Pyrex 0.8 provides a couple of different ways of
+solving this problem. The best way, especially if you have many C
+functions to wrap, is probably to put the extern C function
+declarations into a different namespace using the facilities described
+in the section on <a href="sharing.html">sharing
+declarations between Pyrex modules</a>. </p> <p>The
+other way is to use a <b>c name specification</b> to give
+different Pyrex and C names to the C function. Suppose, for example,
+that you want to wrap an external function called <tt>eject_tomato</tt>.
+If you declare it as </p> <blockquote> <pre>cdef extern void c_eject_tomato "eject_tomato" (float speed)</pre>
+</blockquote> then its name inside the Pyrex module will be <tt>c_eject_tomato</tt>,
+whereas its name in C will be <tt>eject_tomato</tt>. You
+can then wrap it with <blockquote> <pre>def eject_tomato(speed):<br>&nbsp; c_eject_tomato(speed)</pre>
+</blockquote> so that users of your module can refer to it as <tt>eject_tomato</tt>.
+<p>Another use for this feature is referring to external names
+that happen to be Pyrex keywords. For example, if you want to call an
+external function called <tt>print</tt>, you can rename it
+to something else in your Pyrex module. </p> <p>As well
+as functions, C names can be specified for variables, structs, unions,
+enums, struct and union members, and enum values. For example, </p>
+<blockquote> <pre>cdef extern int one "ein", two "zwei"<br>cdef extern float three "drei"<br><br>cdef struct spam "SPAM":<br>&nbsp; int i "eye"</pre><tt>cdef
+enum surprise "inquisition":</tt> <br> <tt>&nbsp;
+first "alpha"</tt> <br> <tt>&nbsp; second
+"beta" = 3</tt></blockquote> <hr width="100%">
+<h2><a name="Using_Pyrex_Declarations_from_C"></a>Using
+Pyrex Declarations from C</h2>Pyrex
+provides two methods for making C declarations from a Pyrex module
+available for use by external C code &#8211; public declarations and C API
+declarations.<br><br><div style="margin-left: 40px;"><span style="font-weight: bold;">NOTE:</span> You do <span style="font-style: italic;">not</span> need to use
+either of these to make declarations from one Pyrex module available to
+another Pyrex module &#8211; you should use the <span style="font-weight: bold;">cimport</span> statement
+for that. <a href="sharing.html">Sharing Declarations
+Between Pyrex Modules</a>.</div><h3><a name="PublicDecls"></a>Public Declarations</h3>
+You can make C types, variables and functions defined in a Pyrex module
+accessible to C code that is linked with the module, by declaring them
+with the <b><tt>public</tt></b> keyword: <blockquote><tt>cdef
+public struct Bunny: # public type declaration<br>&nbsp;
+&nbsp; int vorpalness<br><br>cdef public int spam #
+public variable declaration</tt> <p><tt>cdef public
+void grail(Bunny *): # public function declaration</tt> <br>
+<tt>&nbsp;&nbsp;&nbsp; ...</tt></p> </blockquote>
+If there are any <tt>public</tt> declarations in a Pyrex
+module, a header file called <b><span style="font-style: italic;">modulename</span>.h</b>
+file is generated containing equivalent C declarations for inclusion in
+other C code.<br><br>Any
+C code wanting to make use of these declarations will need to be
+linked, either statically or dynamically, with the extension module.<br><br>If
+the Pyrex module resides within a package, then the name of the .h file
+consists of the full dotted name of the module, e.g. a module called <span style="font-weight: bold;">foo.spam</span> would have
+a header file called <span style="font-weight: bold;">foo.spam.h</span>.
+<h3><a name="C_API_Declarations"></a>C API
+Declarations</h3><p>The other way of making declarations available to C code is to declare them with the <span style="font-family: monospace; font-weight: bold;">api</span>
+keyword. You can use this keyword with C functions and extension types. A header file called "<span style="font-weight: bold;"><span style="font-style: italic;">modulename</span>_api.h</span>"
+is produced containing declarations of the functions and extension types, and a function
+called <span style="font-weight: bold;">import_<span style="font-style: italic;">modulename</span>()</span>.</p><p>C
+code wanting to use these functions or extension types needs to include the header and call
+the import_<span style="font-style: italic;">modulename</span>()
+function. The other functions can then be called and the extension types used as usual.</p><p>Any
+<span style="font-family: monospace;">public</span>
+C type or extension type declarations in the Pyrex module are also made available when you
+include <span style="font-style: italic;">modulename</span>_api.h.</p><table style="text-align: left; width: 100%;" border="0" cellpadding="5" cellspacing="2"><tbody><tr><td style="background-color: rgb(102, 204, 204);"><pre>delorean.pyx</pre></td><td style="background-color: rgb(255, 153, 0);"><pre>marty.c</pre></td></tr><tr><td style="vertical-align: top; background-color: rgb(102, 204, 204);"><pre>cdef public struct Vehicle:<br> int speed<br> float power<br><br>cdef api void activate(Vehicle *v):<br> if v.speed &gt;= 88 \<br> and v.power &gt;= 1.21:<br> print "Time travel achieved"</pre></td><td style="background-color: rgb(255, 153, 0);"><pre>#include "delorean_api.h"<br><br>Vehicle car;<br><br>int main(int argc, char *argv[]) {<br> import_delorean();<br> car.speed = atoi(argv[1]);<br> car.power = atof(argv[2]);&nbsp;<br> activate(&amp;car);<br>}</pre></td></tr></tbody></table><br>Note
+that any types defined in the Pyrex module that are used as argument or
+return types of the exported functions will need to be declared <span style="font-family: monospace;">public</span>,
+otherwise they won't be included in the generated header file, and you
+will get errors when you try to compile a C file that uses the header.<br><br>Using the <span style="font-family: monospace;">api</span> method does not require the C code using the declarations to be linked
+with the extension module in any way, as the Python import machinery is
+used to make the connection dynamically. However, only functions can be
+accessed this way, not variables.<br><br>You can use both <span style="font-family: monospace;">public</span> and <span style="font-family: monospace;">api</span> on the same
+function to make it available by both methods, e.g.<br><pre style="margin-left: 40px;">cdef public api void belt_and_braces():<br> ...<br></pre>However,
+note that you should include <span style="font-weight: bold;">either</span>
+<span style="font-style: italic;">modulename</span>.h
+<span style="font-weight: bold;">or</span> <span style="font-style: italic;">modulename</span>_api.h in
+a given C file, <span style="font-style: italic;">not</span>
+both, otherwise you may get conflicting dual definitions.<br><br>If
+the Pyrex module resides within a package, then:<br><ul><li>The
+name of the header file contains of the full dotted name of the module.</li><li>The
+name of the importing function contains the full name with dots
+replaced by double underscores.</li></ul>E.g. a module
+called <span style="font-weight: bold;">foo.spam</span>
+would have an API header file called <span style="font-weight: bold;">foo.spam_api.h</span> and
+an importing function called <span style="font-weight: bold;">import_foo__spam()</span>.<br><h3><a name="Multiple_public_and_api_declarations"></a>Multiple public and api declarations</h3>You can declare a whole group of items as <span style="font-style: italic;">public</span> and/or <span style="font-style: italic;">api</span> all at once by enclosing them in a cdef block, for example,<br><pre style="margin-left: 40px;">cdef public api:<br> void order_spam(int tons)<br> char *get_lunch(float tomato_size)<br></pre>This can be a useful thing to do in a <span style="font-family: monospace;">.pxd</span> file (see <a href="sharing.html">Sharing Declarations
+Between Pyrex Modules</a>) to make the module's public interface available by all three methods.<br><br><hr style="width: 100%; height: 2px;"><h2><a name="Acquiring_and_Releasing_the_GIL"></a>Acquiring and Releasing the GIL</h2>Pyrex
+provides facilities for releasing the Global Interpreter Lock (GIL)
+before calling C code, and for acquiring the GIL in functions that are
+to be called back from C code that is executed without the GIL.<br><h3>Releasing the GIL</h3>You can release the GIL around a section of code using the<span style="font-family: monospace; font-weight: bold;"> with nogil </span>statement:<br><pre style="margin-left: 40px;">with nogil:<br> &lt;code to be executed with the GIL released&gt;<br></pre>Code in the body of the statement <span style="font-style: italic;">must not manipulate Python objects</span>,
+and must
+not call anything that manipulates Python objects without first
+re-acquiring the GIL. Pyrex attempts to check that these restrictions
+are being followed as far as it can, but it may not catch all possible
+forms of violation<span style="font-weight: bold;"></span>.<br><br>Any external C functions called inside the block must be declared as <span style="font-family: monospace;">nogil</span> (<a href="#nogil">see below</a>).<br><br><span style="font-weight: bold;">Note</span>:
+It may be safe to do some things with Python objects under some
+circumstances. Provided steps are taken (such as adequate locking) to
+ensure that the objects involved cannot be deallocated by Python code
+running in another thread, it is probably safe to access non-Python C
+attributes of an extension type, and to pass references to Python
+objects to another function that is safe to call with the GIL released.<br><br>However, in the absence of such locking, it is not safe to do <span style="font-style: italic;">anything</span> with Python objects with the GIL released -- not even look at them.<br><h3>Acquiring the GIL</h3>A
+C function that is to be used as a callback from C code that is executed
+without the GIL needs to acquire the GIL before it can manipulate
+Python objects. This can be done by specifying<span style="font-family: monospace; font-weight: bold;"> with gil </span>in the function header:<br><pre style="margin-left: 40px;">cdef void my_callback(void *data) with gil:<br> ...<br></pre><h3><a name="nogil"></a>Declaring a function as callable without the GIL</h3>You can specify <span style="font-family: monospace; font-weight: bold;">nogil</span> in a C function header or function type to declare that it is safe to call without the GIL.<br><br><div style="margin-left: 40px;"><span style="font-family: monospace;">cdef extern int swizzle_the_knob() nogil</span><br></div><br>A block of external functions can be declared <span style="font-family: monospace;">nogil</span> at once.<br><br><div style="margin-left: 40px;"><span style="font-family: monospace;">cdef extern from "somewhere.h" nogil:</span><br style="font-family: monospace;"><div style="margin-left: 40px;"><span style="font-family: monospace;">...</span><br></div></div><br>Note that declaring a function <span style="font-family: monospace;">nogil</span> does <span style="font-style: italic;">not</span>
+cause the GIL to be released before calling the function. It simply
+allows the function to be called in situations where the GIL is not
+held.<br><br>You can also declare a function implemented in Pyrex as <span style="font-family: monospace;">nogil</span>.<br><pre style="margin-left: 40px;">cdef void my_gil_free_func(int spam) nogil:<br> ...</pre>Such a function cannot have any Python local variables, it cannot return a
+Python type, and the same restrictions apply to the body of the function as for a<span style="font-family: monospace;"> with nogil </span>block.<br><br>Declaring a function<span style="font-family: monospace;"> with gil </span>also implicitly makes its signature<span style="font-family: monospace;"> nogil</span>.<br><br>
+<hr style="width: 100%; height: 2px;"><span style="font-weight: bold;">Footnotes</span>
+<hr width="100%"><a name="Footnote1"></a>1.
+A problem with const
+could arise if you have something like <blockquote> <pre>cdef extern from "grail.h":<br>&nbsp; char *nun</pre>
+</blockquote> where grail.h actually contains <blockquote>
+<pre>extern const char *nun;</pre> </blockquote> and
+you do <blockquote> <pre>cdef void languissement(char *s):<br>&nbsp; #something that doesn't change s</pre>
+<pre>...</pre> <pre>languissement(nun)</pre> </blockquote>which
+will cause the C compiler to complain. You can work around it by
+casting away the constness: <blockquote> <pre>languissement(&lt;char *&gt;nun)&nbsp; <br></pre>
+</blockquote>---</body></html> \ No newline at end of file