| ======================================================= |
| Overview |
| ======================================================= |
| |
| .. contents:: |
| |
| |
| The first section presents a simple working |
| example of using CFFI to call a C function in a compiled shared object |
| (DLL) from Python. CFFI is |
| flexible and covers several other use cases presented in the second |
| section. The third section shows how to export Python functions |
| to a Python interpreter embedded in a C or C++ application. The last |
| two sections delve deeper in the CFFI library. |
| |
| Make sure you have `cffi installed`__. |
| |
| .. __: installation.html |
| |
| .. _out-of-line-api-level: |
| .. _real-example: |
| |
| |
| Main mode of usage |
| ------------------ |
| |
| The main way to use CFFI is as an interface to some already-compiled |
| shared object which is provided by other means. Imagine that you have a |
| system-installed shared object called ``piapprox.dll`` (Windows) or |
| ``libpiapprox.so`` (Linux and others) or ``libpiapprox.dylib`` (OS X), |
| exporting a function ``float pi_approx(int n);`` that computes some |
| approximation of pi given a number of iterations. You want to call |
| this function from Python. Note this method works equally well with a |
| static library ``piapprox.lib`` (Windows) or ``libpiapprox.a``. |
| |
| Create the file ``piapprox_build.py``: |
| |
| .. code-block:: python |
| |
| from cffi import FFI |
| ffibuilder = FFI() |
| |
| # cdef() expects a single string declaring the C types, functions and |
| # globals needed to use the shared object. It must be in valid C syntax. |
| ffibuilder.cdef(""" |
| float pi_approx(int n); |
| """) |
| |
| # set_source() gives the name of the python extension module to |
| # produce, and some C source code as a string. This C code needs |
| # to make the declarated functions, types and globals available, |
| # so it is often just the "#include". |
| ffibuilder.set_source("_pi_cffi", |
| """ |
| #include "pi.h" // the C header of the library |
| """, |
| libraries=['piapprox']) # library name, for the linker |
| |
| if __name__ == "__main__": |
| ffibuilder.compile(verbose=True) |
| |
| Execute this script. If everything is OK, it should produce |
| ``_pi_cffi.c``, and then invoke the compiler on it. The produced |
| ``_pi_cffi.c`` contains a copy of the string given in ``set_source()``, |
| in this example the ``#include "pi.h"``. Afterwards, it contains glue code |
| for all the functions, types and globals declared in the ``cdef()`` above. |
| |
| At runtime, you use the extension module like this: |
| |
| .. code-block:: python |
| |
| from _pi_cffi import ffi, lib |
| print(lib.pi_approx(5000)) |
| |
| That's all! In the rest of this page, we describe some more advanced |
| examples and other CFFI modes. In particular, there is a complete |
| example `if you don't have an already-installed C library to call`_. |
| |
| For more information about the ``cdef()`` and ``set_source()`` methods |
| of the ``FFI`` class, see `Preparing and Distributing modules`__. |
| |
| .. __: cdef.html |
| |
| When your example works, a common alternative to running the build |
| script manually is to have it run as part of a ``setup.py``. Here is |
| an example using the Setuptools distribution: |
| |
| .. code-block:: python |
| |
| from setuptools import setup |
| |
| setup( |
| ... |
| setup_requires=["cffi>=1.0.0"], |
| cffi_modules=["piapprox_build:ffibuilder"], # "filename:global" |
| install_requires=["cffi>=1.0.0"], |
| ) |
| |
| |
| Other CFFI modes |
| ---------------- |
| |
| CFFI can be used in one of four modes: "ABI" versus "API" level, |
| each with "in-line" or "out-of-line" preparation (or compilation). |
| |
| The **ABI mode** accesses libraries at the binary level, whereas the |
| faster **API mode** accesses them with a C compiler. We explain the |
| difference in more details below__. |
| |
| .. __: `abi-versus-api`_ |
| |
| In the **in-line mode,** everything is set up every time you import |
| your Python code. In the **out-of-line mode,** you have a separate |
| step of preparation (and possibly C compilation) that produces a |
| module which your main program can then import. |
| |
| |
| Simple example (ABI level, in-line) |
| +++++++++++++++++++++++++++++++++++ |
| |
| May look familiar to those who have used ctypes_. |
| |
| .. code-block:: python |
| |
| >>> from cffi import FFI |
| >>> ffi = FFI() |
| >>> ffi.cdef(""" |
| ... int printf(const char *format, ...); // copy-pasted from the man page |
| ... """) |
| >>> C = ffi.dlopen(None) # loads the entire C namespace |
| >>> arg = ffi.new("char[]", b"world") # equivalent to C code: char arg[] = "world"; |
| >>> C.printf(b"hi there, %s.\n", arg) # call printf |
| hi there, world. |
| 17 # this is the return value |
| >>> |
| |
| Note that ``char *`` arguments expect a ``bytes`` object. If you have a |
| ``str`` (or a ``unicode`` on Python 2) you need to encode it explicitly |
| with ``somestring.encode(myencoding)``. |
| |
| *Python 3 on Windows:* ``ffi.dlopen(None)`` does not work. This problem |
| is messy and not really fixable. The problem does not occur if you try |
| to call a function from a specific DLL that exists on your system: then |
| you use ``ffi.dlopen("path.dll")``. |
| |
| *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().* |
| |
| If using a C compiler to install your module is an option, it is highly |
| recommended to use the API mode instead. (It is also faster.) |
| |
| |
| Struct/Array Example (minimal, in-line) |
| +++++++++++++++++++++++++++++++++++++++ |
| |
| .. code-block:: python |
| |
| from cffi import FFI |
| ffi = FFI() |
| ffi.cdef(""" |
| typedef struct { |
| unsigned char r, g, b; |
| } pixel_t; |
| """) |
| image = ffi.new("pixel_t[]", 800*600) |
| |
| f = open('data', 'rb') # binary mode -- important |
| f.readinto(ffi.buffer(image)) |
| f.close() |
| |
| image[100].r = 255 |
| image[100].g = 192 |
| image[100].b = 128 |
| |
| f = open('data', 'wb') |
| f.write(ffi.buffer(image)) |
| f.close() |
| |
| This can be used as a more flexible replacement of the struct_ and |
| array_ modules, and replaces ctypes_. You could also call ``ffi.new("pixel_t[600][800]")`` |
| and get a two-dimensional array. |
| |
| .. _struct: http://docs.python.org/library/struct.html |
| .. _array: http://docs.python.org/library/array.html |
| .. _ctypes: http://docs.python.org/library/ctypes.html |
| |
| *This example does not call any C compiler.* |
| |
| This example also admits an out-of-line equivalent. It is similar to |
| the first example `Main mode of usage`_ above, |
| but passing ``None`` as the second argument to |
| ``ffibuilder.set_source()``. Then in the main program you write |
| ``from _simple_example import ffi`` and then the same content as the |
| in-line example above starting from the line ``image = |
| ffi.new("pixel_t[]", 800*600)``. |
| |
| |
| API Mode, calling the C standard library |
| ++++++++++++++++++++++++++++++++++++++++ |
| |
| .. code-block:: python |
| |
| # file "example_build.py" |
| |
| # Note: we instantiate the same 'cffi.FFI' class as in the previous |
| # example, but call the result 'ffibuilder' now instead of 'ffi'; |
| # this is to avoid confusion with the other 'ffi' object you get below |
| |
| from cffi import FFI |
| ffibuilder = FFI() |
| |
| ffibuilder.set_source("_example", |
| r""" // passed to the real C compiler, |
| // contains implementation of things declared in cdef() |
| #include <sys/types.h> |
| #include <pwd.h> |
| |
| // We can also define custom wrappers or other functions |
| // here (this is an example only): |
| static struct passwd *get_pw_for_root(void) { |
| return getpwuid(0); |
| } |
| """, |
| libraries=[]) # or a list of libraries to link with |
| # (more arguments like setup.py's Extension class: |
| # include_dirs=[..], extra_objects=[..], and so on) |
| |
| ffibuilder.cdef(""" |
| // declarations that are shared between Python and C |
| struct passwd { |
| char *pw_name; |
| ...; // literally dot-dot-dot |
| }; |
| struct passwd *getpwuid(int uid); // defined in <pwd.h> |
| struct passwd *get_pw_for_root(void); // defined in set_source() |
| """) |
| |
| if __name__ == "__main__": |
| ffibuilder.compile(verbose=True) |
| |
| You need to run the ``example_build.py`` script once to generate |
| "source code" into the file ``_example.c`` 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 |
| ``set_source()`` is ``None`` or not.) |
| |
| *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.* |
| |
| Then, in your main program, you use: |
| |
| .. code-block:: python |
| |
| from _example import ffi, lib |
| |
| p = lib.getpwuid(0) |
| assert ffi.string(p.pw_name) == b'root' |
| p = lib.get_pw_for_root() |
| assert ffi.string(p.pw_name) == b'root' |
| |
| Note that this works independently of the exact C layout of ``struct |
| passwd`` (it is "API level", as opposed to "ABI level"). It requires |
| a C compiler in order to run ``example_build.py``, but it is much more |
| portable than trying to get the details of the fields of ``struct |
| passwd`` exactly right. Similarly, in the ``cdef()`` we declared |
| ``getpwuid()`` as taking an ``int`` argument; on some platforms this |
| might be slightly incorrect---but it does not matter. |
| |
| Note also that at runtime, the API mode is faster than the ABI mode. |
| |
| To integrate it inside a ``setup.py`` distribution with Setuptools: |
| |
| .. code-block:: python |
| |
| from setuptools import setup |
| |
| setup( |
| ... |
| setup_requires=["cffi>=1.0.0"], |
| cffi_modules=["example_build.py:ffibuilder"], |
| install_requires=["cffi>=1.0.0"], |
| ) |
| |
| |
| .. _`if you don't have an already-installed C library to call`: |
| |
| API Mode, calling C sources instead of a compiled library |
| +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
| |
| If you want to call some library that is not precompiled, but for which |
| you have C sources, then the easiest solution is to make a single |
| extension module that is compiled from both the C sources of this |
| library, and the additional CFFI wrappers. For example, say you start |
| with the files ``pi.c`` and ``pi.h``: |
| |
| .. code-block:: C |
| |
| /* filename: pi.c*/ |
| # include <stdlib.h> |
| # include <math.h> |
| |
| /* Returns a very crude approximation of Pi |
| given a int: a number of iteration */ |
| float pi_approx(int n){ |
| |
| double i,x,y,sum=0; |
| |
| for(i=0;i<n;i++){ |
| |
| x=rand(); |
| y=rand(); |
| |
| if (sqrt(x*x+y*y) < sqrt((double)RAND_MAX*RAND_MAX)) |
| sum++; } |
| |
| return 4*(float)sum/(float)n; } |
| |
| .. code-block:: C |
| |
| /* filename: pi.h*/ |
| float pi_approx(int n); |
| |
| Create a script named ``pi_extension_build.py``, building |
| the C extension: |
| |
| .. code-block:: python |
| |
| from cffi import FFI |
| ffibuilder = FFI() |
| |
| ffibuilder.cdef("float pi_approx(int n);") |
| |
| ffibuilder.set_source("_pi", # name of the output C extension |
| """ |
| #include "pi.h"', |
| """, |
| sources=['pi.c'], # includes pi.c as additional sources |
| libraries=['m']) # on Unix, link with the math library |
| |
| if __name__ == "__main__": |
| ffibuilder.compile(verbose=True) |
| |
| Build the extension: |
| |
| .. code-block:: shell |
| |
| python pi_extension_build.py |
| |
| Observe, in the working directory, the generated output files: |
| ``_pi.c``, ``_pi.o`` and the compiled C extension (called ``_pi.so`` on |
| Linux for example). It can be called from Python: |
| |
| .. code-block:: python |
| |
| from _pi.lib import pi_approx |
| |
| approx = pi_approx(10) |
| assert str(pi_approximation).startswith("3.") |
| |
| approx = pi_approx(10000) |
| assert str(approx).startswith("3.1") |
| |
| |
| .. _performance: |
| |
| Purely for performance (API level, out-of-line) |
| +++++++++++++++++++++++++++++++++++++++++++++++ |
| |
| A variant of the `section above`__ 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: |
| |
| .. __: real-example_ |
| |
| .. code-block:: python |
| |
| # file "example_build.py" |
| |
| from cffi import FFI |
| ffibuilder = FFI() |
| |
| ffibuilder.cdef("int foo(int *, int *, int);") |
| |
| ffibuilder.set_source("_example", |
| r""" |
| static int foo(int *buffer_in, int *buffer_out, int x) |
| { |
| /* some algorithm that is seriously faster in C than in Python */ |
| } |
| """) |
| |
| if __name__ == "__main__": |
| ffibuilder.compile(verbose=True) |
| |
| .. code-block:: python |
| |
| # file "example.py" |
| |
| from _example import ffi, lib |
| |
| buffer_in = ffi.new("int[]", 1000) |
| # initialize buffer_in here... |
| |
| # easier to do all buffer allocations in Python and pass them to C, |
| # even for output-only arguments |
| buffer_out = ffi.new("int[]", 1000) |
| |
| result = lib.foo(buffer_in, buffer_out, 1000) |
| |
| *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.* |
| |
| |
| .. _out-of-line-abi-level: |
| |
| Out-of-line, ABI level |
| ++++++++++++++++++++++ |
| |
| 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). |
| |
| 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 ``cdef()`` many times with small pieces of declarations, |
| based on the version of libraries detected on the system). |
| |
| .. code-block:: python |
| |
| # file "simple_example_build.py" |
| |
| from cffi import FFI |
| |
| ffibuilder = FFI() |
| # Note that the actual source is None |
| ffibuilder.set_source("_simple_example", None) |
| ffibuilder.cdef(""" |
| int printf(const char *format, ...); |
| """) |
| |
| if __name__ == "__main__": |
| ffibuilder.compile(verbose=True) |
| |
| Running it once produces ``_simple_example.py``. Your main program |
| only imports this generated module, not ``simple_example_build.py`` |
| any more: |
| |
| .. code-block:: python |
| |
| from _simple_example import ffi |
| |
| lib = ffi.dlopen(None) # Unix: open the standard C library |
| #import ctypes.util # or, try this on Windows: |
| #lib = ffi.dlopen(ctypes.util.find_library("c")) |
| |
| lib.printf(b"hi there, number %d\n", ffi.cast("int", 2)) |
| |
| Note that this ``ffi.dlopen()``, 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 |
| ``dlopen()`` or ``LoadLibrary()`` functions. This means that |
| ``ffi.dlopen("libfoo.so")`` is ok, but ``ffi.dlopen("foo")`` is not. |
| In the latter case, you could replace it with |
| ``ffi.dlopen(ctypes.util.find_library("foo"))``. Also, None is only |
| recognized on Unix to open the standard C library. |
| |
| For distribution purposes, remember that there is a new |
| ``_simple_example.py`` file generated. You can either include it |
| statically within your project's source files, or, with Setuptools, |
| you can say in the ``setup.py``: |
| |
| .. code-block:: python |
| |
| from setuptools import setup |
| |
| setup( |
| ... |
| setup_requires=["cffi>=1.0.0"], |
| cffi_modules=["simple_example_build.py:ffibuilder"], |
| install_requires=["cffi>=1.0.0"], |
| ) |
| |
| In summary, this mode is useful when you wish to declare many C structures but |
| do not need fast interaction with a shared object. It is useful for parsing |
| binary files, for instance. |
| |
| |
| In-line, API level |
| ++++++++++++++++++ |
| |
| The "API level + in-line" mode combination exists but is long |
| deprecated. It used to be done with ``lib = ffi.verify("C header")``. |
| The out-of-line variant with ``set_source("modname", "C header")`` is |
| preferred and avoids a number of problems when the project grows in |
| size. |
| |
| |
| .. _embedding: |
| |
| Embedding |
| --------- |
| |
| *New in version 1.5.* |
| |
| CFFI can be used for embedding__: creating a standard |
| dynamically-linked library (``.dll`` under Windows, ``.so`` elsewhere) |
| which can be used from a C application. |
| |
| .. code-block:: python |
| |
| import cffi |
| ffibuilder = cffi.FFI() |
| |
| ffibuilder.embedding_api(""" |
| int do_stuff(int, int); |
| """) |
| |
| ffibuilder.set_source("my_plugin", "") |
| |
| ffibuilder.embedding_init_code(""" |
| from my_plugin import ffi |
| |
| @ffi.def_extern() |
| def do_stuff(x, y): |
| print("adding %d and %d" % (x, y)) |
| return x + y |
| """) |
| |
| ffibuilder.compile(target="plugin-1.5.*", verbose=True) |
| |
| This simple example creates ``plugin-1.5.dll`` or ``plugin-1.5.so`` as |
| a DLL with a single exported function, ``do_stuff()``. 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 ``int do_stuff(int, |
| int)``, the Python interpreter is automatically initialized and ``def |
| do_stuff(x, y):`` gets called. `See the details in the documentation |
| about embedding.`__ |
| |
| .. __: embedding.html |
| .. __: embedding.html |
| |
| |
| What actually happened? |
| ----------------------- |
| |
| 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. |
| |
| The declarations can contain **types, functions, constants** |
| and **global variables.** What you pass to the ``cdef()`` must not |
| contain more than that; in particular, ``#ifdef`` or ``#include`` |
| 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". |
| |
| In the ABI examples, the ``dlopen()`` 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 |
| ``dlopen()`` returns a ``<FFILibrary>`` 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 |
| ``cdef()``. If you have several interdependent libraries to load, |
| you would call ``cdef()`` only once but ``dlopen()`` several times. |
| |
| 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 ``libraries`` keyword argument to |
| ``set_source()``, but never need to say which symbol comes |
| from which library. |
| Other common arguments to ``set_source()`` include ``library_dirs`` and |
| ``include_dirs``; all these arguments are passed to the standard |
| distutils/setuptools. |
| |
| The ``ffi.new()`` 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. |
| |
| The actual ``lib.*()`` function calls should be obvious: it's like C. |
| |
| |
| .. _abi-versus-api: |
| |
| ABI versus API |
| -------------- |
| |
| Accessing the C library at the binary level ("ABI") is fraught |
| with problems, particularly on non-Windows platforms. |
| |
| The most immediate drawback of the ABI level is that calling functions |
| needs to go through the very general *libffi* library, which is slow |
| (and not always perfectly tested on non-standard platforms). The API |
| mode instead compiles a CPython C wrapper that directly invokes the |
| target function. It can be massively faster (and works |
| better than libffi ever will). |
| |
| The more fundamental reason to prefer the API mode is that *the C |
| libraries are typically meant to be used with a C compiler.* You are not |
| supposed to do things like guess where fields are in the structures. |
| The "real example" above shows how CFFI uses a C compiler under the |
| hood: this example uses ``set_source(..., "C source...")`` and never |
| ``dlopen()``. When using this approach, |
| we have the advantage that we can use literally "``...``" at various places in |
| the ``cdef()``, and the missing information will be completed with the |
| help of the C compiler. CFFI will turn this into a single C source file, |
| which contains the "C source" part unmodified, followed by some |
| "magic" C code and declarations derived from the ``cdef()``. 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. |
| |
| Note that the "C source" part from ``set_source()`` 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 ``cdef()`` too. |
| (You can use the ``static`` C keyword in the "C source" part, |
| as in ``static int myhelper(int x) { return x * 42; }``, |
| because these helpers are only |
| referenced from the "magic" C code that is generated afterwards in the |
| same C file.) |
| |
| 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 ``cdef()`` as if they were |
| functions.) |
| |
| 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 ``_cffi_backend`` |
| module, on CPython). The special Setuptools lines in the `example |
| above`__ 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. |
| |
| .. __: real-example_ |