EVOLUTION-MANAGER
Edit File: overview.html
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <title>Overview — CFFI 1.9.1 documentation</title> <link rel="stylesheet" href="_static/default.css" type="text/css" /> <link rel="stylesheet" href="_static/pygments.css" type="text/css" /> <script type="text/javascript"> var DOCUMENTATION_OPTIONS = { URL_ROOT: '', VERSION: '1.9.1', COLLAPSE_INDEX: false, FILE_SUFFIX: '.html', HAS_SOURCE: true }; </script> <script type="text/javascript" src="_static/jquery.js"></script> <script type="text/javascript" src="_static/underscore.js"></script> <script type="text/javascript" src="_static/doctools.js"></script> <link rel="top" title="CFFI 1.9.1 documentation" href="index.html" /> <link rel="next" title="Using the ffi/lib objects" href="using.html" /> <link rel="prev" title="Installation and Status" href="installation.html" /> </head> <body> <div class="related"> <h3>Navigation</h3> <ul> <li class="right" style="margin-right: 10px"> <a href="genindex.html" title="General Index" accesskey="I">index</a></li> <li class="right" > <a href="using.html" title="Using the ffi/lib objects" accesskey="N">next</a> |</li> <li class="right" > <a href="installation.html" title="Installation and Status" accesskey="P">previous</a> |</li> <li><a href="index.html">CFFI 1.9.1 documentation</a> »</li> </ul> </div> <div class="document"> <div class="documentwrapper"> <div class="bodywrapper"> <div class="body"> <div class="section" id="overview"> <h1><a class="toc-backref" href="#id10">Overview</a><a class="headerlink" href="#overview" title="Permalink to this headline">¶</a></h1> <div class="contents topic" id="contents"> <p class="topic-title first">Contents</p> <ul class="simple"> <li><a class="reference internal" href="#overview" id="id10">Overview</a><ul> <li><a class="reference internal" href="#simple-example-abi-level-in-line" id="id11">Simple example (ABI level, in-line)</a></li> <li><a class="reference internal" href="#real-example-api-level-out-of-line" id="id12">Real example (API level, out-of-line)</a></li> <li><a class="reference internal" href="#struct-array-example-minimal-in-line" id="id13">Struct/Array Example (minimal, in-line)</a></li> <li><a class="reference internal" href="#purely-for-performance-api-level-out-of-line" id="id14">Purely for performance (API level, out-of-line)</a></li> <li><a class="reference internal" href="#out-of-line-abi-level" id="id15">Out-of-line, ABI level</a></li> <li><a class="reference internal" href="#embedding" id="id16">Embedding</a></li> <li><a class="reference internal" href="#what-actually-happened" id="id17">What actually happened?</a></li> <li><a class="reference internal" href="#abi-versus-api" id="id18">ABI versus API</a></li> </ul> </li> </ul> </div> <p>CFFI can be used in one of four modes: “ABI” versus “API” level, each with “in-line” or “out-of-line” preparation (or compilation).</p> <p>The <strong>ABI mode</strong> accesses libraries at the binary level, whereas the <strong>API mode</strong> accesses them with a C compiler. This is described in detail <a class="reference internal" href="#abi-versus-api">below</a>.</p> <p>In the <strong>in-line mode,</strong> everything is set up every time you import your Python code. In the <strong>out-of-line mode,</strong> you have a separate step of preparation (and possibly C compilation) that produces a module which your main program can then import.</p> <p>(The examples below assume that you have <a class="reference external" href="installation.html">installed CFFI</a>.)</p> <div class="section" id="simple-example-abi-level-in-line"> <h2><a class="toc-backref" href="#id11">Simple example (ABI level, in-line)</a><a class="headerlink" href="#simple-example-abi-level-in-line" title="Permalink to this headline">¶</a></h2> <div class="highlight-python"><div class="highlight"><pre><span class="gp">>>> </span><span class="kn">from</span> <span class="nn">cffi</span> <span class="kn">import</span> <span class="n">FFI</span> <span class="gp">>>> </span><span class="n">ffi</span> <span class="o">=</span> <span class="n">FFI</span><span class="p">()</span> <span class="gp">>>> </span><span class="n">ffi</span><span class="o">.</span><span class="n">cdef</span><span class="p">(</span><span class="s">"""</span> <span class="gp">... </span><span class="s"> int printf(const char *format, ...); // copy-pasted from the man page</span> <span class="gp">... </span><span class="s">"""</span><span class="p">)</span> <span class="gp">>>> </span><span class="n">C</span> <span class="o">=</span> <span class="n">ffi</span><span class="o">.</span><span class="n">dlopen</span><span class="p">(</span><span class="bp">None</span><span class="p">)</span> <span class="c"># loads the entire C namespace</span> <span class="gp">>>> </span><span class="n">arg</span> <span class="o">=</span> <span class="n">ffi</span><span class="o">.</span><span class="n">new</span><span class="p">(</span><span class="s">"char[]"</span><span class="p">,</span> <span class="s">"world"</span><span class="p">)</span> <span class="c"># equivalent to C code: char arg[] = "world";</span> <span class="gp">>>> </span><span class="n">C</span><span class="o">.</span><span class="n">printf</span><span class="p">(</span><span class="s">"hi there, </span><span class="si">%s</span><span class="s">.</span><span class="se">\n</span><span class="s">"</span><span class="p">,</span> <span class="n">arg</span><span class="p">)</span> <span class="c"># call printf</span> <span class="go">hi there, world.</span> <span class="go">17 # this is the return value</span> <span class="go">>>></span> </pre></div> </div> <p>Note that on Python 3 you need to pass byte strings to <tt class="docutils literal"><span class="pre">char</span> <span class="pre">*</span></tt> arguments. In the above example it would be <tt class="docutils literal"><span class="pre">b"world"</span></tt> and <tt class="docutils literal"><span class="pre">b"hi</span> <span class="pre">there,</span> <span class="pre">%s!\n"</span></tt>. In general it is <tt class="docutils literal"><span class="pre">somestring.encode(myencoding)</span></tt>.</p> <p><em>This example does not call any C compiler. It works in the so-called ABI mode, which means that it will crash if you call some function or access some fields of a structure that was slightly misdeclared in the cdef().</em></p> <p>If using a C compiler to install your module is an option, it is highly recommended to use the API mode described in the next paragraph. (It is also a bit faster at runtime.)</p> </div> <div class="section" id="real-example-api-level-out-of-line"> <span id="real-example"></span><span id="out-of-line-api-level"></span><h2><a class="toc-backref" href="#id12">Real example (API level, out-of-line)</a><a class="headerlink" href="#real-example-api-level-out-of-line" title="Permalink to this headline">¶</a></h2> <div class="highlight-python"><div class="highlight"><pre><span class="c"># file "example_build.py"</span> <span class="c"># Note: we instantiate the same 'cffi.FFI' class as in the previous</span> <span class="c"># example, but call the result 'ffibuilder' now instead of 'ffi';</span> <span class="c"># this is to avoid confusion with the other 'ffi' object you get below</span> <span class="kn">from</span> <span class="nn">cffi</span> <span class="kn">import</span> <span class="n">FFI</span> <span class="n">ffibuilder</span> <span class="o">=</span> <span class="n">FFI</span><span class="p">()</span> <span class="n">ffibuilder</span><span class="o">.</span><span class="n">set_source</span><span class="p">(</span><span class="s">"_example"</span><span class="p">,</span> <span class="sd">r""" // passed to the real C compiler</span> <span class="sd"> #include <sys/types.h></span> <span class="sd"> #include <pwd.h></span> <span class="sd"> """</span><span class="p">,</span> <span class="n">libraries</span><span class="o">=</span><span class="p">[])</span> <span class="c"># or a list of libraries to link with</span> <span class="c"># (more arguments like setup.py's Extension class:</span> <span class="c"># include_dirs=[..], extra_objects=[..], and so on)</span> <span class="n">ffibuilder</span><span class="o">.</span><span class="n">cdef</span><span class="p">(</span><span class="s">""" // some declarations from the man page</span> <span class="s"> struct passwd {</span> <span class="s"> char *pw_name;</span> <span class="s"> ...; // literally dot-dot-dot</span> <span class="s"> };</span> <span class="s"> struct passwd *getpwuid(int uid);</span> <span class="s">"""</span><span class="p">)</span> <span class="k">if</span> <span class="n">__name__</span> <span class="o">==</span> <span class="s">"__main__"</span><span class="p">:</span> <span class="n">ffibuilder</span><span class="o">.</span><span class="n">compile</span><span class="p">(</span><span class="n">verbose</span><span class="o">=</span><span class="bp">True</span><span class="p">)</span> </pre></div> </div> <p>You need to run the <tt class="docutils literal"><span class="pre">example_build.py</span></tt> script once to generate “source code” into the file <tt class="docutils literal"><span class="pre">_example.c</span></tt> and compile this to a regular C extension module. (CFFI selects either Python or C for the module to generate based on whether the second argument to <tt class="docutils literal"><span class="pre">set_source()</span></tt> is <tt class="docutils literal"><span class="pre">None</span></tt> or not.)</p> <p><em>You need a C compiler for this single step. It produces a file called e.g. _example.so or _example.pyd. If needed, it can be distributed in precompiled form like any other extension module.</em></p> <p>Then, in your main program, you use:</p> <div class="highlight-python"><div class="highlight"><pre><span class="kn">from</span> <span class="nn">_example</span> <span class="kn">import</span> <span class="n">ffi</span><span class="p">,</span> <span class="n">lib</span> <span class="n">p</span> <span class="o">=</span> <span class="n">lib</span><span class="o">.</span><span class="n">getpwuid</span><span class="p">(</span><span class="mi">0</span><span class="p">)</span> <span class="k">assert</span> <span class="n">ffi</span><span class="o">.</span><span class="n">string</span><span class="p">(</span><span class="n">p</span><span class="o">.</span><span class="n">pw_name</span><span class="p">)</span> <span class="o">==</span> <span class="n">b</span><span class="s">'root'</span> </pre></div> </div> <p>Note that this works independently of the exact C layout of <tt class="docutils literal"><span class="pre">struct</span> <span class="pre">passwd</span></tt> (it is “API level”, as opposed to “ABI level”). It requires a C compiler in order to run <tt class="docutils literal"><span class="pre">example_build.py</span></tt>, but it is much more portable than trying to get the details of the fields of <tt class="docutils literal"><span class="pre">struct</span> <span class="pre">passwd</span></tt> exactly right. Similarly, we declared <tt class="docutils literal"><span class="pre">getpwuid()</span></tt> as taking an <tt class="docutils literal"><span class="pre">int</span></tt> argument. On some platforms this might be slightly incorrect—but it does not matter.</p> <p>To integrate it inside a <tt class="docutils literal"><span class="pre">setup.py</span></tt> distribution with Setuptools:</p> <div class="highlight-python"><div class="highlight"><pre><span class="kn">from</span> <span class="nn">setuptools</span> <span class="kn">import</span> <span class="n">setup</span> <span class="n">setup</span><span class="p">(</span> <span class="o">...</span> <span class="n">setup_requires</span><span class="o">=</span><span class="p">[</span><span class="s">"cffi>=1.0.0"</span><span class="p">],</span> <span class="n">cffi_modules</span><span class="o">=</span><span class="p">[</span><span class="s">"example_build.py:ffibuilder"</span><span class="p">],</span> <span class="n">install_requires</span><span class="o">=</span><span class="p">[</span><span class="s">"cffi>=1.0.0"</span><span class="p">],</span> <span class="p">)</span> </pre></div> </div> </div> <div class="section" id="struct-array-example-minimal-in-line"> <h2><a class="toc-backref" href="#id13">Struct/Array Example (minimal, in-line)</a><a class="headerlink" href="#struct-array-example-minimal-in-line" title="Permalink to this headline">¶</a></h2> <div class="highlight-python"><div class="highlight"><pre><span class="kn">from</span> <span class="nn">cffi</span> <span class="kn">import</span> <span class="n">FFI</span> <span class="n">ffi</span> <span class="o">=</span> <span class="n">FFI</span><span class="p">()</span> <span class="n">ffi</span><span class="o">.</span><span class="n">cdef</span><span class="p">(</span><span class="s">"""</span> <span class="s"> typedef struct {</span> <span class="s"> unsigned char r, g, b;</span> <span class="s"> } pixel_t;</span> <span class="s">"""</span><span class="p">)</span> <span class="n">image</span> <span class="o">=</span> <span class="n">ffi</span><span class="o">.</span><span class="n">new</span><span class="p">(</span><span class="s">"pixel_t[]"</span><span class="p">,</span> <span class="mi">800</span><span class="o">*</span><span class="mi">600</span><span class="p">)</span> <span class="n">f</span> <span class="o">=</span> <span class="nb">open</span><span class="p">(</span><span class="s">'data'</span><span class="p">,</span> <span class="s">'rb'</span><span class="p">)</span> <span class="c"># binary mode -- important</span> <span class="n">f</span><span class="o">.</span><span class="n">readinto</span><span class="p">(</span><span class="n">ffi</span><span class="o">.</span><span class="n">buffer</span><span class="p">(</span><span class="n">image</span><span class="p">))</span> <span class="n">f</span><span class="o">.</span><span class="n">close</span><span class="p">()</span> <span class="n">image</span><span class="p">[</span><span class="mi">100</span><span class="p">]</span><span class="o">.</span><span class="n">r</span> <span class="o">=</span> <span class="mi">255</span> <span class="n">image</span><span class="p">[</span><span class="mi">100</span><span class="p">]</span><span class="o">.</span><span class="n">g</span> <span class="o">=</span> <span class="mi">192</span> <span class="n">image</span><span class="p">[</span><span class="mi">100</span><span class="p">]</span><span class="o">.</span><span class="n">b</span> <span class="o">=</span> <span class="mi">128</span> <span class="n">f</span> <span class="o">=</span> <span class="nb">open</span><span class="p">(</span><span class="s">'data'</span><span class="p">,</span> <span class="s">'wb'</span><span class="p">)</span> <span class="n">f</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="n">ffi</span><span class="o">.</span><span class="n">buffer</span><span class="p">(</span><span class="n">image</span><span class="p">))</span> <span class="n">f</span><span class="o">.</span><span class="n">close</span><span class="p">()</span> </pre></div> </div> <p>This can be used as a more flexible replacement of the <a class="reference external" href="http://docs.python.org/library/struct.html">struct</a> and <a class="reference external" href="http://docs.python.org/library/array.html">array</a> modules. You could also call <tt class="docutils literal"><span class="pre">ffi.new("pixel_t[600][800]")</span></tt> and get a two-dimensional array.</p> <p><em>This example does not call any C compiler.</em></p> <p>This example also admits an out-of-line equivalent. It is similar to <a class="reference internal" href="#real-example-api-level-out-of-line">Real example (API level, out-of-line)</a> above, but passing <tt class="docutils literal"><span class="pre">None</span></tt> as the second argument to <tt class="docutils literal"><span class="pre">ffibuilder.set_source()</span></tt>. Then in the main program you write <tt class="docutils literal"><span class="pre">from</span> <span class="pre">_simple_example</span> <span class="pre">import</span> <span class="pre">ffi</span></tt> and then the same content as the in-line example above starting from the line <tt class="docutils literal"><span class="pre">image</span> <span class="pre">=</span> <span class="pre">ffi.new("pixel_t[]",</span> <span class="pre">800*600)</span></tt>.</p> </div> <div class="section" id="purely-for-performance-api-level-out-of-line"> <span id="performance"></span><h2><a class="toc-backref" href="#id14">Purely for performance (API level, out-of-line)</a><a class="headerlink" href="#purely-for-performance-api-level-out-of-line" title="Permalink to this headline">¶</a></h2> <p>A variant of the <a class="reference internal" href="#real-example">section above</a> where the goal is not to call an existing C library, but to compile and call some C function written directly in the build script:</p> <div class="highlight-python"><div class="highlight"><pre><span class="c"># file "example_build.py"</span> <span class="kn">from</span> <span class="nn">cffi</span> <span class="kn">import</span> <span class="n">FFI</span> <span class="n">ffibuilder</span> <span class="o">=</span> <span class="n">FFI</span><span class="p">()</span> <span class="n">ffibuilder</span><span class="o">.</span><span class="n">cdef</span><span class="p">(</span><span class="s">"int foo(int *, int *, int);"</span><span class="p">)</span> <span class="n">ffibuilder</span><span class="o">.</span><span class="n">set_source</span><span class="p">(</span><span class="s">"_example"</span><span class="p">,</span> <span class="sd">r"""</span> <span class="sd"> static int foo(int *buffer_in, int *buffer_out, int x)</span> <span class="sd"> {</span> <span class="sd"> /* some algorithm that is seriously faster in C than in Python */</span> <span class="sd"> }</span> <span class="sd">"""</span><span class="p">)</span> <span class="k">if</span> <span class="n">__name__</span> <span class="o">==</span> <span class="s">"__main__"</span><span class="p">:</span> <span class="n">ffibuilder</span><span class="o">.</span><span class="n">compile</span><span class="p">(</span><span class="n">verbose</span><span class="o">=</span><span class="bp">True</span><span class="p">)</span> </pre></div> </div> <div class="highlight-python"><div class="highlight"><pre><span class="c"># file "example.py"</span> <span class="kn">from</span> <span class="nn">_example</span> <span class="kn">import</span> <span class="n">ffi</span><span class="p">,</span> <span class="n">lib</span> <span class="n">buffer_in</span> <span class="o">=</span> <span class="n">ffi</span><span class="o">.</span><span class="n">new</span><span class="p">(</span><span class="s">"int[]"</span><span class="p">,</span> <span class="mi">1000</span><span class="p">)</span> <span class="c"># initialize buffer_in here...</span> <span class="c"># easier to do all buffer allocations in Python and pass them to C,</span> <span class="c"># even for output-only arguments</span> <span class="n">buffer_out</span> <span class="o">=</span> <span class="n">ffi</span><span class="o">.</span><span class="n">new</span><span class="p">(</span><span class="s">"int[]"</span><span class="p">,</span> <span class="mi">1000</span><span class="p">)</span> <span class="n">result</span> <span class="o">=</span> <span class="n">lib</span><span class="o">.</span><span class="n">foo</span><span class="p">(</span><span class="n">buffer_in</span><span class="p">,</span> <span class="n">buffer_out</span><span class="p">,</span> <span class="mi">1000</span><span class="p">)</span> </pre></div> </div> <p><em>You need a C compiler to run example_build.py, once. It produces a file called e.g. _example.so or _example.pyd. If needed, it can be distributed in precompiled form like any other extension module.</em></p> </div> <div class="section" id="out-of-line-abi-level"> <span id="id4"></span><h2><a class="toc-backref" href="#id15">Out-of-line, ABI level</a><a class="headerlink" href="#out-of-line-abi-level" title="Permalink to this headline">¶</a></h2> <p>The out-of-line ABI mode is a mixture of the regular (API) out-of-line mode and the in-line ABI mode. It lets you use the ABI mode, with its advantages (not requiring a C compiler) and problems (crashes more easily).</p> <p>This mixture mode lets you massively reduces the import times, because it is slow to parse a large C header. It also allows you to do more detailed checkings during build-time without worrying about performance (e.g. calling <tt class="docutils literal"><span class="pre">cdef()</span></tt> many times with small pieces of declarations, based on the version of libraries detected on the system).</p> <div class="highlight-python"><div class="highlight"><pre><span class="c"># file "simple_example_build.py"</span> <span class="kn">from</span> <span class="nn">cffi</span> <span class="kn">import</span> <span class="n">FFI</span> <span class="n">ffibuilder</span> <span class="o">=</span> <span class="n">FFI</span><span class="p">()</span> <span class="n">ffibuilder</span><span class="o">.</span><span class="n">set_source</span><span class="p">(</span><span class="s">"_simple_example"</span><span class="p">,</span> <span class="bp">None</span><span class="p">)</span> <span class="n">ffibuilder</span><span class="o">.</span><span class="n">cdef</span><span class="p">(</span><span class="s">"""</span> <span class="s"> int printf(const char *format, ...);</span> <span class="s">"""</span><span class="p">)</span> <span class="k">if</span> <span class="n">__name__</span> <span class="o">==</span> <span class="s">"__main__"</span><span class="p">:</span> <span class="n">ffibuilder</span><span class="o">.</span><span class="n">compile</span><span class="p">(</span><span class="n">verbose</span><span class="o">=</span><span class="bp">True</span><span class="p">)</span> </pre></div> </div> <p>Running it once produces <tt class="docutils literal"><span class="pre">_simple_example.py</span></tt>. Your main program only imports this generated module, not <tt class="docutils literal"><span class="pre">simple_example_build.py</span></tt> any more:</p> <div class="highlight-python"><div class="highlight"><pre><span class="kn">from</span> <span class="nn">_simple_example</span> <span class="kn">import</span> <span class="n">ffi</span> <span class="n">lib</span> <span class="o">=</span> <span class="n">ffi</span><span class="o">.</span><span class="n">dlopen</span><span class="p">(</span><span class="bp">None</span><span class="p">)</span> <span class="c"># Unix: open the standard C library</span> <span class="c">#import ctypes.util # or, try this on Windows:</span> <span class="c">#lib = ffi.dlopen(ctypes.util.find_library("c"))</span> <span class="n">lib</span><span class="o">.</span><span class="n">printf</span><span class="p">(</span><span class="n">b</span><span class="s">"hi there, number </span><span class="si">%d</span><span class="se">\n</span><span class="s">"</span><span class="p">,</span> <span class="n">ffi</span><span class="o">.</span><span class="n">cast</span><span class="p">(</span><span class="s">"int"</span><span class="p">,</span> <span class="mi">2</span><span class="p">))</span> </pre></div> </div> <p>Note that this <tt class="docutils literal"><span class="pre">ffi.dlopen()</span></tt>, unlike the one from in-line mode, does not invoke any additional magic to locate the library: it must be a path name (with or without a directory), as required by the C <tt class="docutils literal"><span class="pre">dlopen()</span></tt> or <tt class="docutils literal"><span class="pre">LoadLibrary()</span></tt> functions. This means that <tt class="docutils literal"><span class="pre">ffi.dlopen("libfoo.so")</span></tt> is ok, but <tt class="docutils literal"><span class="pre">ffi.dlopen("foo")</span></tt> is not. In the latter case, you could replace it with <tt class="docutils literal"><span class="pre">ffi.dlopen(ctypes.util.find_library("foo"))</span></tt>. Also, None is only recognized on Unix to open the standard C library.</p> <p>For distribution purposes, remember that there is a new <tt class="docutils literal"><span class="pre">_simple_example.py</span></tt> file generated. You can either include it statically within your project’s source files, or, with Setuptools, you can say in the <tt class="docutils literal"><span class="pre">setup.py</span></tt>:</p> <div class="highlight-python"><div class="highlight"><pre><span class="kn">from</span> <span class="nn">setuptools</span> <span class="kn">import</span> <span class="n">setup</span> <span class="n">setup</span><span class="p">(</span> <span class="o">...</span> <span class="n">setup_requires</span><span class="o">=</span><span class="p">[</span><span class="s">"cffi>=1.0.0"</span><span class="p">],</span> <span class="n">cffi_modules</span><span class="o">=</span><span class="p">[</span><span class="s">"simple_example_build.py:ffibuilder"</span><span class="p">],</span> <span class="n">install_requires</span><span class="o">=</span><span class="p">[</span><span class="s">"cffi>=1.0.0"</span><span class="p">],</span> <span class="p">)</span> </pre></div> </div> </div> <div class="section" id="embedding"> <span id="id5"></span><h2><a class="toc-backref" href="#id16">Embedding</a><a class="headerlink" href="#embedding" title="Permalink to this headline">¶</a></h2> <p><em>New in version 1.5.</em></p> <p>CFFI can be used for <a class="reference external" href="embedding.html">embedding</a>: creating a standard dynamically-linked library (<tt class="docutils literal"><span class="pre">.dll</span></tt> under Windows, <tt class="docutils literal"><span class="pre">.so</span></tt> elsewhere) which can be used from a C application.</p> <div class="highlight-python"><div class="highlight"><pre><span class="kn">import</span> <span class="nn">cffi</span> <span class="n">ffibuilder</span> <span class="o">=</span> <span class="n">cffi</span><span class="o">.</span><span class="n">FFI</span><span class="p">()</span> <span class="n">ffibuilder</span><span class="o">.</span><span class="n">embedding_api</span><span class="p">(</span><span class="s">"""</span> <span class="s"> int do_stuff(int, int);</span> <span class="s">"""</span><span class="p">)</span> <span class="n">ffibuilder</span><span class="o">.</span><span class="n">set_source</span><span class="p">(</span><span class="s">"my_plugin"</span><span class="p">,</span> <span class="s">""</span><span class="p">)</span> <span class="n">ffibuilder</span><span class="o">.</span><span class="n">embedding_init_code</span><span class="p">(</span><span class="s">"""</span> <span class="s"> from my_plugin import ffi</span> <span class="s"> @ffi.def_extern()</span> <span class="s"> def do_stuff(x, y):</span> <span class="s"> print("adding </span><span class="si">%d</span><span class="s"> and </span><span class="si">%d</span><span class="s">" % (x, y))</span> <span class="s"> return x + y</span> <span class="s">"""</span><span class="p">)</span> <span class="n">ffibuilder</span><span class="o">.</span><span class="n">compile</span><span class="p">(</span><span class="n">target</span><span class="o">=</span><span class="s">"plugin-1.5.*"</span><span class="p">,</span> <span class="n">verbose</span><span class="o">=</span><span class="bp">True</span><span class="p">)</span> </pre></div> </div> <p>This simple example creates <tt class="docutils literal"><span class="pre">plugin-1.5.dll</span></tt> or <tt class="docutils literal"><span class="pre">plugin-1.5.so</span></tt> as a DLL with a single exported function, <tt class="docutils literal"><span class="pre">do_stuff()</span></tt>. You execute the script above once, with the interpreter you want to have internally used; it can be CPython 2.x or 3.x or PyPy. This DLL can then be used “as usual” from an application; the application doesn’t need to know that it is talking with a library made with Python and CFFI. At runtime, when the application calls <tt class="docutils literal"><span class="pre">int</span> <span class="pre">do_stuff(int,</span> <span class="pre">int)</span></tt>, the Python interpreter is automatically initialized and <tt class="docutils literal"><span class="pre">def</span> <span class="pre">do_stuff(x,</span> <span class="pre">y):</span></tt> gets called. <a class="reference external" href="embedding.html">See the details in the documentation about embedding.</a></p> </div> <div class="section" id="what-actually-happened"> <h2><a class="toc-backref" href="#id17">What actually happened?</a><a class="headerlink" href="#what-actually-happened" title="Permalink to this headline">¶</a></h2> <p>The CFFI interface operates on the same level as C - you declare types and functions using the same syntax as you would define them in C. This means that most of the documentation or examples can be copied straight from the man pages.</p> <p>The declarations can contain <strong>types, functions, constants</strong> and <strong>global variables.</strong> What you pass to the <tt class="docutils literal"><span class="pre">cdef()</span></tt> must not contain more than that; in particular, <tt class="docutils literal"><span class="pre">#ifdef</span></tt> or <tt class="docutils literal"><span class="pre">#include</span></tt> directives are not supported. The cdef in the above examples are just that - they declared “there is a function in the C level with this given signature”, or “there is a struct type with this shape”.</p> <p>In the ABI examples, the <tt class="docutils literal"><span class="pre">dlopen()</span></tt> calls load libraries manually. At the binary level, a program is split into multiple namespaces—a global one (on some platforms), plus one namespace per library. So <tt class="docutils literal"><span class="pre">dlopen()</span></tt> returns a <tt class="docutils literal"><span class="pre"><FFILibrary></span></tt> object, and this object has got as attributes all function, constant and variable symbols that are coming from this library and that have been declared in the <tt class="docutils literal"><span class="pre">cdef()</span></tt>. If you have several interdependent libraries to load, you would call <tt class="docutils literal"><span class="pre">cdef()</span></tt> only once but <tt class="docutils literal"><span class="pre">dlopen()</span></tt> several times.</p> <p>By opposition, the API mode works more closely like a C program: the C linker (static or dynamic) is responsible for finding any symbol used. You name the libraries in the <tt class="docutils literal"><span class="pre">libraries</span></tt> keyword argument to <tt class="docutils literal"><span class="pre">set_source()</span></tt>, but never need to say which symbol comes from which library. Other common arguments to <tt class="docutils literal"><span class="pre">set_source()</span></tt> include <tt class="docutils literal"><span class="pre">library_dirs</span></tt> and <tt class="docutils literal"><span class="pre">include_dirs</span></tt>; all these arguments are passed to the standard distutils/setuptools.</p> <p>The <tt class="docutils literal"><span class="pre">ffi.new()</span></tt> lines allocate C objects. They are filled with zeroes initially, unless the optional second argument is used. If specified, this argument gives an “initializer”, like you can use with C code to initialize global variables.</p> <p>The actual <tt class="docutils literal"><span class="pre">lib.*()</span></tt> function calls should be obvious: it’s like C.</p> </div> <div class="section" id="abi-versus-api"> <span id="id8"></span><h2><a class="toc-backref" href="#id18">ABI versus API</a><a class="headerlink" href="#abi-versus-api" title="Permalink to this headline">¶</a></h2> <p>Accessing the C library at the binary level (“ABI”) is fraught with problems, particularly on non-Windows platforms. You are not meant to access fields by guessing where they are in the structures. <em>The C libraries are typically meant to be used with a C compiler.</em></p> <p>The “real example” above shows how to do that: this example uses <tt class="docutils literal"><span class="pre">set_source(...,</span> <span class="pre">"C</span> <span class="pre">source...")</span></tt> and never <tt class="docutils literal"><span class="pre">dlopen()</span></tt>. When using this approach, we have the advantage that we can use literally “<tt class="docutils literal"><span class="pre">...</span></tt>” at various places in the <tt class="docutils literal"><span class="pre">cdef()</span></tt>, and the missing information will be completed with the help of the C compiler. Actually, a single C source file is produced, which contains first the “C source” part unmodified, followed by some “magic” C code and declarations derived from the <tt class="docutils literal"><span class="pre">cdef()</span></tt>. When this C file is compiled, the resulting C extension module will contain all the information we need—or the C compiler will give warnings or errors, as usual e.g. if we misdeclare some function’s signature.</p> <p>Note that the “C source” part from <tt class="docutils literal"><span class="pre">set_source()</span></tt> can contain arbitrary C code. You can use this to declare some more helper functions written in C. To export these helpers to Python, put their signature in the <tt class="docutils literal"><span class="pre">cdef()</span></tt> too. (You can use the <tt class="docutils literal"><span class="pre">static</span></tt> C keyword in the “C source” part, as in <tt class="docutils literal"><span class="pre">static</span> <span class="pre">int</span> <span class="pre">myhelper(int</span> <span class="pre">x)</span> <span class="pre">{</span> <span class="pre">return</span> <span class="pre">x</span> <span class="pre">*</span> <span class="pre">42;</span> <span class="pre">}</span></tt>, because these helpers are only referenced from the “magic” C code that is generated afterwards in the same C file.)</p> <p>This can be used for example to wrap “crazy” macros into more standard C functions. The extra layer of C can be useful for other reasons too, like calling functions that expect some complicated argument structures that you prefer to build in C rather than in Python. (On the other hand, if all you need is to call “function-like” macros, then you can directly declare them in the <tt class="docutils literal"><span class="pre">cdef()</span></tt> as if they were functions.)</p> <p>The generated piece of C code should be the same independently on the platform on which you run it (or the Python version), so in simple cases you can directly distribute the pre-generated C code and treat it as a regular C extension module (which depends on the <tt class="docutils literal"><span class="pre">_cffi_backend</span></tt> module, on CPython). The special Setuptools lines in the <a class="reference internal" href="#real-example">example above</a> are meant for the more complicated cases where we need to regenerate the C sources as well—e.g. because the Python script that regenerates this file will itself look around the system to know what it should include or not.</p> <p>Note that the “API level + in-line” mode combination exists but is long deprecated. It used to be done with <tt class="docutils literal"><span class="pre">lib</span> <span class="pre">=</span> <span class="pre">ffi.verify("C</span> <span class="pre">header")</span></tt>. The out-of-line variant with <tt class="docutils literal"><span class="pre">set_source("modname",</span> <span class="pre">"C</span> <span class="pre">header")</span></tt> is preferred.</p> </div> </div> </div> </div> </div> <div class="sphinxsidebar"> <div class="sphinxsidebarwrapper"> <h3><a href="index.html">Table Of Contents</a></h3> <ul> <li><a class="reference internal" href="#">Overview</a><ul> <li><a class="reference internal" href="#simple-example-abi-level-in-line">Simple example (ABI level, in-line)</a></li> <li><a class="reference internal" href="#real-example-api-level-out-of-line">Real example (API level, out-of-line)</a></li> <li><a class="reference internal" href="#struct-array-example-minimal-in-line">Struct/Array Example (minimal, in-line)</a></li> <li><a class="reference internal" href="#purely-for-performance-api-level-out-of-line">Purely for performance (API level, out-of-line)</a></li> <li><a class="reference internal" href="#out-of-line-abi-level">Out-of-line, ABI level</a></li> <li><a class="reference internal" href="#embedding">Embedding</a></li> <li><a class="reference internal" href="#what-actually-happened">What actually happened?</a></li> <li><a class="reference internal" href="#abi-versus-api">ABI versus API</a></li> </ul> </li> </ul> <h4>Previous topic</h4> <p class="topless"><a href="installation.html" title="previous chapter">Installation and Status</a></p> <h4>Next topic</h4> <p class="topless"><a href="using.html" title="next chapter">Using the ffi/lib objects</a></p> <h3>This Page</h3> <ul class="this-page-menu"> <li><a href="_sources/overview.txt" rel="nofollow">Show Source</a></li> </ul> <div id="searchbox" style="display: none"> <h3>Quick search</h3> <form class="search" action="search.html" method="get"> <input type="text" name="q" /> <input type="submit" value="Go" /> <input type="hidden" name="check_keywords" value="yes" /> <input type="hidden" name="area" value="default" /> </form> <p class="searchtip" style="font-size: 90%"> Enter search terms or a module, class or function name. </p> </div> <script type="text/javascript">$('#searchbox').show(0);</script> </div> </div> <div class="clearer"></div> </div> <div class="related"> <h3>Navigation</h3> <ul> <li class="right" style="margin-right: 10px"> <a href="genindex.html" title="General Index" >index</a></li> <li class="right" > <a href="using.html" title="Using the ffi/lib objects" >next</a> |</li> <li class="right" > <a href="installation.html" title="Installation and Status" >previous</a> |</li> <li><a href="index.html">CFFI 1.9.1 documentation</a> »</li> </ul> </div> <div class="footer"> © Copyright 2012-2015, Armin Rigo, Maciej Fijalkowski. Created using <a href="http://sphinx.pocoo.org/">Sphinx</a> 1.1.3. </div> </body> </html>