You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
294 lines
24 KiB
294 lines
24 KiB
4 years ago
|
<!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>
|