diff options
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.html | 294 |
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> int spam_counter</pre><pre> 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> + <li> It prevents Pyrex from generating any C code for +the declarations found in the associated block.<br> </li> + <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> + <li> Leave out any platform-specific extensions to C +declarations such as <b>__declspec()</b>.<br> </li> + <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> cdef extern +from "foo.h":<br> +struct spam:<br> + 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> <li> +If the header file uses macros to define constants, translate them into +a dummy <b>enum</b> declaration.<br> </li> + <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> +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> +...</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"> </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> ...</tt> <br> <tt>};</tt></td> +<td bgcolor="#66cccc"><tt>cdef struct Foo:</tt> +<br> <tt> ...</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> ...</tt> <br> +<tt>} Foo;</tt></td> <td bgcolor="#66cccc" valign="top"><tt>ctypedef struct Foo:</tt> <br> +<tt> ...</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> ...</tt> <br> +<tt>} Foo;</tt></td> <td bgcolor="#66cccc" nowrap="nowrap" valign="top"><tt>cdef struct +foo:</tt> <br> <tt> ...</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> ...</tt></td> </tr> <tr bgcolor="#8cbc1c" valign="top"> <td>4</td> +<td bgcolor="#ff9900" nowrap="nowrap"><tt>typedef +struct Foo {</tt> <br> <tt> ...</tt> +<br> <tt>} Foo;</tt></td> <td bgcolor="#66cccc" valign="top"><tt>cdef struct +Foo:</tt> <br> <tt> ...</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> 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> 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> int i "eye"</pre><tt>cdef +enum surprise "inquisition":</tt> <br> <tt> +first "alpha"</tt> <br> <tt> 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 – 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 – 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> + 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> ...</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 >= 88 \<br> and v.power >= 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]); <br> activate(&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> <code to be executed with the GIL released><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> 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> #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(<char *>nun) <br></pre> +</blockquote>---</body></html>
\ No newline at end of file |