| ======================================================= | |
| 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_ |