| ====================================== |
| Preparing and Distributing modules |
| ====================================== |
| |
| .. contents:: |
| |
| There are three or four different ways to use CFFI in a project. |
| In order of complexity: |
| |
| * The **"in-line", "ABI mode"**: |
| |
| .. code-block:: python |
| |
| import cffi |
| |
| ffi = cffi.FFI() |
| ffi.cdef("C-like declarations") |
| lib = ffi.dlopen("libpath") |
| |
| # use ffi and lib here |
| |
| .. _out-of-line-abi: |
| |
| * The **"out-of-line",** but still **"ABI mode",** useful to organize |
| the code and reduce the import time: |
| |
| .. code-block:: python |
| |
| # in a separate file "package/foo_build.py" |
| import cffi |
| |
| ffibuilder = cffi.FFI() |
| ffibuilder.set_source("package._foo", None) |
| ffibuilder.cdef("C-like declarations") |
| |
| if __name__ == "__main__": |
| ffibuilder.compile() |
| |
| Running ``python foo_build.py`` produces a file ``_foo.py``, which |
| can then be imported in the main program: |
| |
| .. code-block:: python |
| |
| from package._foo import ffi |
| lib = ffi.dlopen("libpath") |
| |
| # use ffi and lib here |
| |
| .. _out-of-line-api: |
| |
| * The **"out-of-line", "API mode"** gives you the most flexibility |
| and speed to access a C library at the level of C, instead of at the |
| binary level: |
| |
| .. code-block:: python |
| |
| # in a separate file "package/foo_build.py" |
| import cffi |
| |
| ffibuilder = cffi.FFI() |
| ffibuilder.set_source("package._foo", r"""real C code""") # <= |
| ffibuilder.cdef("C-like declarations with '...'") |
| |
| if __name__ == "__main__": |
| ffibuilder.compile(verbose=True) |
| |
| Running ``python foo_build.py`` produces a file ``_foo.c`` and |
| invokes the C compiler to turn it into a file ``_foo.so`` (or |
| ``_foo.pyd`` or ``_foo.dylib``). It is a C extension module which |
| can be imported in the main program: |
| |
| .. code-block:: python |
| |
| from package._foo import ffi, lib |
| # no ffi.dlopen() |
| |
| # use ffi and lib here |
| |
| .. _distutils-setuptools: |
| |
| * Finally, you can (but don't have to) use CFFI's **Distutils** or |
| **Setuptools integration** when writing a ``setup.py``. For |
| Distutils (only in out-of-line API mode): |
| |
| .. code-block:: python |
| |
| # setup.py (requires CFFI to be installed first) |
| from distutils.core import setup |
| |
| import foo_build # possibly with sys.path tricks to find it |
| |
| setup( |
| ..., |
| ext_modules=[foo_build.ffibuilder.distutils_extension()], |
| ) |
| |
| For Setuptools (out-of-line, but works in ABI or API mode; |
| recommended): |
| |
| .. code-block:: python |
| |
| # setup.py (with automatic dependency tracking) |
| from setuptools import setup |
| |
| setup( |
| ..., |
| setup_requires=["cffi>=1.0.0"], |
| cffi_modules=["package/foo_build.py:ffibuilder"], |
| install_requires=["cffi>=1.0.0"], |
| ) |
| |
| Note again that the ``foo_build.py`` example contains the following |
| lines, which mean that the ``ffibuilder`` is not actually compiled |
| when ``package.foo_build`` is merely imported---it will be compiled |
| independently by the Setuptools logic, using compilation parameters |
| provided by Setuptools: |
| |
| .. code-block:: python |
| |
| if __name__ == "__main__": # not when running with setuptools |
| ffibuilder.compile(verbose=True) |
| |
| * Note that some bundler tools that try to find all modules used by a |
| project, like PyInstaller, will miss ``_cffi_backend`` in the |
| out-of-line mode because your program contains no explicit ``import |
| cffi`` or ``import _cffi_backend``. You need to add |
| ``_cffi_backend`` explicitly (as a "hidden import" in PyInstaller, |
| but it can also be done more generally by adding the line ``import |
| _cffi_backend`` in your main program). |
| |
| Note that CFFI actually contains two different ``FFI`` classes. The |
| page `Using the ffi/lib objects`_ describes the common functionality. |
| It is what you get in the ``from package._foo import ffi`` lines above. |
| On the other hand, the extended ``FFI`` class is the one you get from |
| ``import cffi; ffi_or_ffibuilder = cffi.FFI()``. It has the same |
| functionality (for in-line use), but also the extra methods described |
| below (to prepare the FFI). NOTE: We use the name ``ffibuilder`` |
| instead of ``ffi`` in the out-of-line context, when the code is about |
| producing a ``_foo.so`` file; this is an attempt to distinguish it |
| from the different ``ffi`` object that you get by later saying |
| ``from _foo import ffi``. |
| |
| .. _`Using the ffi/lib objects`: using.html |
| |
| The reason for this split of functionality is that a regular program |
| using CFFI out-of-line does not need to import the ``cffi`` pure |
| Python package at all. (Internally it still needs ``_cffi_backend``, |
| a C extension module that comes with CFFI; this is why CFFI is also |
| listed in ``install_requires=..`` above. In the future this might be |
| split into a different PyPI package that only installs |
| ``_cffi_backend``.) |
| |
| Note that a few small differences do exist: notably, ``from _foo import |
| ffi`` returns an object of a type written in C, which does not let you |
| add random attributes to it (nor does it have all the |
| underscore-prefixed internal attributes of the Python version). |
| Similarly, the ``lib`` objects returned by the C version are read-only, |
| apart from writes to global variables. Also, ``lib.__dict__`` does |
| not work before version 1.2 or if ``lib`` happens to declare a name |
| called ``__dict__`` (use instead ``dir(lib)``). The same is true |
| for ``lib.__class__``, ``lib.__all__`` and ``lib.__name__`` added |
| in successive versions. |
| |
| |
| .. _cdef: |
| |
| ffi/ffibuilder.cdef(): declaring types and functions |
| ---------------------------------------------------- |
| |
| **ffi/ffibuilder.cdef(source)**: parses the given C source. |
| It registers all the functions, types, constants and global variables in |
| the C source. The types can be used immediately in ``ffi.new()`` and |
| other functions. Before you can access the functions and global |
| variables, you need to give ``ffi`` another piece of information: where |
| they actually come from (which you do with either ``ffi.dlopen()`` or |
| ``ffi.set_source()``). |
| |
| .. _`all types listed above`: |
| |
| The C source is parsed internally (using ``pycparser``). This code |
| cannot contain ``#include``. It should typically be a self-contained |
| piece of declarations extracted from a man page. The only things it |
| can assume to exist are the standard types: |
| |
| * char, short, int, long, long long (both signed and unsigned) |
| |
| * float, double, long double |
| |
| * intN_t, uintN_t (for N=8,16,32,64), intptr_t, uintptr_t, ptrdiff_t, |
| size_t, ssize_t |
| |
| * wchar_t (if supported by the backend). *New in version 1.11:* |
| char16_t and char32_t. |
| |
| * _Bool and bool (equivalent). If not directly supported by the C |
| compiler, this is declared with the size of ``unsigned char``. |
| |
| * FILE. `See here.`__ |
| |
| * all `common Windows types`_ are defined if you run |
| on Windows (``DWORD``, ``LPARAM``, etc.). Exception: |
| ``TBYTE TCHAR LPCTSTR PCTSTR LPTSTR PTSTR PTBYTE PTCHAR`` are |
| not automatically defined; see `ffi.set_unicode()`_. |
| |
| * the other standard integer types from |
| stdint.h, like ``intmax_t``, as long as they map to integers of 1, |
| 2, 4 or 8 bytes. Larger integers are not supported. |
| |
| .. __: ref.html#file |
| .. _`common Windows types`: http://msdn.microsoft.com/en-us/library/windows/desktop/aa383751%28v=vs.85%29.aspx |
| |
| The declarations can also contain "``...``" at various places; these are |
| placeholders that will be completed by the compiler. More information |
| about it below in `Letting the C compiler fill the gaps`_. |
| |
| Note that all standard type names listed above are handled as |
| *defaults* only (apart from the ones that are keywords in the C |
| language). If your ``cdef`` contains an explicit typedef that |
| redefines one of the types above, then the default described above is |
| ignored. (This is a bit hard to implement cleanly, so in some corner |
| cases it might fail, notably with the error ``Multiple type specifiers |
| with a type tag``. Please report it as a bug if it does.) |
| |
| Multiple calls to ``ffi.cdef()`` are possible. Beware that it can be |
| slow to call ``ffi.cdef()`` a lot of times, a consideration that is |
| important mainly in in-line mode. |
| |
| The ``ffi.cdef()`` call optionally takes an extra argument: either |
| ``packed`` or ``pack``. If you pass ``packed=True``, |
| then all structs declared within |
| this cdef are "packed". (If you need both packed and non-packed |
| structs, use several cdefs in sequence.) This |
| has a meaning similar to ``__attribute__((packed))`` in GCC. It |
| specifies that all structure fields should have an alignment of one |
| byte. (Note that the packed attribute has no effect on bit fields so |
| far, which mean that they may be packed differently than on GCC. |
| Also, this has no effect on structs declared with ``"...;"``---more |
| about it later in `Letting the C compiler fill the gaps`_.) |
| *New in version 1.12:* In ABI mode, you can also pass ``pack=n``, |
| with an integer ``n`` which must be a power of two. Then the |
| alignment of any field is limited to ``n`` if it would otherwise be |
| greater than ``n``. Passing ``pack=1`` is equivalent to passing |
| ``packed=True``. This is meant to emulate ``#pragma pack(n)`` from |
| the MSVC compiler. On Windows, the default is ``pack=8`` (from cffi |
| 1.12 onwards); on other platforms, the default is ``pack=None``. |
| |
| Note that you can use the type-qualifiers ``const`` and ``restrict`` |
| (but not ``__restrict`` or ``__restrict__``) in the ``cdef()``, but |
| this has no effect on the cdata objects that you get at run-time (they |
| are never ``const``). The effect is limited to knowing if a global |
| variable is meant to be a constant or not. Also, *new in version |
| 1.3:* when using ``set_source()`` or ``verify()``, these two |
| qualifiers are copied from the cdef to the generated C code; this |
| fixes warnings by the C compiler. |
| |
| Note a trick if you copy-paste code from sources in which there are |
| extra macros (for example, the Windows documentation uses SAL |
| annotations like ``_In_`` or ``_Out_``). These hints must be removed |
| in the string given to cdef(), but it can be done programmatically |
| like this:: |
| |
| ffi.cdef(re.sub(r"\b(_In_|_Inout_|_Out_|_Outptr_)(opt_)?\b", " ", |
| """ |
| DWORD WINAPI GetModuleFileName( |
| _In_opt_ HMODULE hModule, |
| _Out_ LPTSTR lpFilename, |
| _In_ DWORD nSize |
| ); |
| """)) |
| |
| Note also that pycparser, the underlying C parser, recognizes |
| preprocessor-like directives in the following format: ``# NUMBER |
| "FILE"``. For example, if you put ``# 42 "foo.h"`` in the middle of the |
| string passed to ``cdef()`` and there is an error two lines later, then |
| it is reported with an error message that starts with ``foo.h:43:`` (the |
| line which is given the number 42 is the line immediately after the |
| directive). *New in version 1.10.1:* CFFI automatically puts the line |
| ``# 1 "<cdef source string>"`` just before the string you give to |
| ``cdef()``. |
| |
| |
| .. _`ffi.set_unicode()`: |
| |
| **ffi.set_unicode(enabled_flag)**: Windows: if ``enabled_flag`` is |
| True, enable the ``UNICODE`` and ``_UNICODE`` defines in C, and |
| declare the types ``TBYTE TCHAR LPCTSTR PCTSTR LPTSTR PTSTR PTBYTE |
| PTCHAR`` to be (pointers to) ``wchar_t``. If ``enabled_flag`` is |
| False, declare these types to be (pointers to) plain 8-bit characters. |
| (These types are not predeclared at all if you don't call |
| ``set_unicode()``.) |
| |
| The reason behind this method is that a lot of standard functions have |
| two versions, like ``MessageBoxA()`` and ``MessageBoxW()``. The |
| official interface is ``MessageBox()`` with arguments like |
| ``LPTCSTR``. Depending on whether ``UNICODE`` is defined or not, the |
| standard header renames the generic function name to one of the two |
| specialized versions, and declares the correct (unicode or not) types. |
| |
| Usually, the right thing to do is to call this method with True. Be |
| aware (particularly on Python 2) that, afterwards, you need to pass unicode |
| strings as arguments instead of byte strings. |
| |
| |
| .. _loading-libraries: |
| |
| ffi.dlopen(): loading libraries in ABI mode |
| ------------------------------------------- |
| |
| ``ffi.dlopen(libpath, [flags])``: this function opens a shared library and |
| returns a module-like library object. Use this when you are fine with |
| the limitations of ABI-level access to the system (dependency on ABI |
| details, getting crashes instead of C compiler errors/warnings, and |
| higher overhead to call the C functions). In case of doubt, read again |
| `ABI versus API`_ in the overview. |
| |
| .. _`ABI versus API`: overview.html#abi-versus-api |
| |
| You can use the library object to call the functions previously |
| declared by ``ffi.cdef()``, to read constants, and to read or write |
| global variables. Note that you can use a single ``cdef()`` to |
| declare functions from multiple libraries, as long as you load each of |
| them with ``dlopen()`` and access the functions from the correct one. |
| |
| The ``libpath`` is the file name of the shared library, which can |
| contain a full path or not (in which case it is searched in standard |
| locations, as described in ``man dlopen``), with extensions or not. |
| Alternatively, if ``libpath`` is None, it returns the standard C library |
| (which can be used to access the functions of glibc, on Linux). Note |
| that ``libpath`` `cannot be None`__ on Windows with Python 3. |
| |
| .. __: http://bugs.python.org/issue23606 |
| |
| Let me state it again: this gives ABI-level access to the library, so |
| you need to have all types declared manually exactly as they were |
| while the library was made. No checking is done. Mismatches can |
| cause random crashes. API-level access, on the other hand, is safer. |
| Speed-wise, API-level access is much faster (it is common to have |
| the opposite misconception about performance). |
| |
| Note that only functions and global variables live in library objects; |
| the types exist in the ``ffi`` instance independently of library objects. |
| This is due to the C model: the types you declare in C are not tied to a |
| particular library, as long as you ``#include`` their headers; but you |
| cannot call functions from a library without linking it in your program, |
| as ``dlopen()`` does dynamically in C. |
| |
| For the optional ``flags`` argument, see ``man dlopen`` (ignored on |
| Windows). It defaults to ``ffi.RTLD_NOW``. |
| |
| This function returns a "library" object that gets closed when it goes |
| out of scope. Make sure you keep the library object around as long as |
| needed. (Alternatively, the out-of-line FFIs have a method |
| ``ffi.dlclose(lib)``.) |
| |
| .. _dlopen-note: |
| |
| Note: the old version of ``ffi.dlopen()`` from the in-line ABI mode |
| tries to use ``ctypes.util.find_library()`` if it cannot directly find |
| the library. The newer out-of-line ``ffi.dlopen()`` no longer does it |
| automatically; it simply passes the argument it receives to the |
| underlying ``dlopen()`` or ``LoadLibrary()`` function. If needed, it |
| is up to you to use ``ctypes.util.find_library()`` or any other way to |
| look for the library's filename. This also means that |
| ``ffi.dlopen(None)`` no longer work on Windows; try instead |
| ``ffi.dlopen(ctypes.util.find_library('c'))``. |
| |
| |
| ffibuilder.set_source(): preparing out-of-line modules |
| ------------------------------------------------------ |
| |
| **ffibuilder.set_source(module_name, c_header_source, [\*\*keywords...])**: |
| prepare the ffi for producing out-of-line an external module called |
| ``module_name``. |
| |
| ``ffibuilder.set_source()`` by itself does not write any file, but merely |
| records its arguments for later. It can therefore be called before or |
| after ``ffibuilder.cdef()``. |
| |
| In **ABI mode,** you call ``ffibuilder.set_source(module_name, None)``. The |
| argument is the name (or dotted name inside a package) of the Python |
| module to generate. In this mode, no C compiler is called. |
| |
| In **API mode,** the ``c_header_source`` argument is a string that |
| will be pasted into the .c file generated. Typically, it is specified as |
| ``r""" ...multiple lines of C code... """`` (the ``r`` prefix allows these |
| lines to contain a literal ``\n``, for example). This piece of C code |
| typically contains some ``#include``, but may also contain more, |
| like definitions for custom "wrapper" C functions. The goal is that |
| the .c file can be generated like this:: |
| |
| // C file "module_name.c" |
| #include <Python.h> |
| |
| ...c_header_source... |
| |
| ...magic code... |
| |
| where the "magic code" is automatically generated from the ``cdef()``. |
| For example, if the ``cdef()`` contains ``int foo(int x);`` then the |
| magic code will contain logic to call the function ``foo()`` with an |
| integer argument, itself wrapped inside some CPython or PyPy-specific |
| code. |
| |
| The keywords arguments to ``set_source()`` control how the C compiler |
| will be called. They are passed directly to distutils_ or setuptools_ |
| and include at least ``sources``, ``include_dirs``, ``define_macros``, |
| ``undef_macros``, ``libraries``, ``library_dirs``, ``extra_objects``, |
| ``extra_compile_args`` and ``extra_link_args``. You typically need at |
| least ``libraries=['foo']`` in order to link with ``libfoo.so`` or |
| ``libfoo.so.X.Y``, or ``foo.dll`` on Windows. The ``sources`` is a |
| list of extra .c files compiled and linked together (the file |
| ``module_name.c`` shown above is always generated and automatically added as the |
| first argument to ``sources``). See the distutils documentations for |
| `more information about the other arguments`__. |
| |
| .. __: http://docs.python.org/distutils/setupscript.html#library-options |
| .. _distutils: http://docs.python.org/distutils/setupscript.html#describing-extension-modules |
| .. _setuptools: https://pythonhosted.org/setuptools/setuptools.html |
| |
| An extra keyword argument processed internally is |
| ``source_extension``, defaulting to ``".c"``. The file generated will |
| be actually called ``module_name + source_extension``. Example for |
| C++ (but note that there are still a few known issues of C-versus-C++ |
| compatibility): |
| |
| .. code-block:: python |
| |
| ffibuilder.set_source("mymodule", r''' |
| extern "C" { |
| int somefunc(int somearg) { return real_cpp_func(somearg); } |
| } |
| ''', source_extension='.cpp') |
| |
| .. _pkgconfig: |
| |
| **ffibuilder.set_source_pkgconfig(module_name, pkgconfig_libs, |
| c_header_source, [\*\*keywords...])**: |
| |
| *New in version 1.12.* This is equivalent to ``set_source()`` but it |
| first calls the system utility ``pkg-config`` with the package names |
| given in the list ``pkgconfig_libs``. It collects the information |
| obtained in this way and adds it to the explicitly-provided |
| ``**keywords`` (if any). This should probably not be used on Windows. |
| |
| If the ``pkg-config`` program is not installed or does not know about |
| the requested library, the call fails with ``cffi.PkgConfigError``. If |
| necessary, you can catch this error and try to call ``set_source()`` |
| directly. (Ideally, you should also do that if the ``ffibuilder`` |
| instance has no method ``set_source_pkgconfig()``, to support older |
| versions of cffi.) |
| |
| |
| Letting the C compiler fill the gaps |
| ------------------------------------ |
| |
| If you are using a C compiler ("API mode"), then: |
| |
| * functions taking or returning integer or float-point arguments can be |
| misdeclared: if e.g. a function is declared by ``cdef()`` as taking a |
| ``int``, but actually takes a ``long``, then the C compiler handles the |
| difference. |
| |
| * other arguments are checked: you get a compilation warning or error |
| if you pass a ``int *`` argument to a function expecting a ``long *``. |
| |
| * similarly, most other things declared in the ``cdef()`` are checked, |
| to the best we implemented so far; mistakes give compilation |
| warnings or errors. |
| |
| Moreover, you can use "``...``" (literally, dot-dot-dot) in the |
| ``cdef()`` at various places, in order to ask the C compiler to fill |
| in the details. These places are: |
| |
| * structure declarations: any ``struct { }`` that ends with "``...;``" as |
| the last "field" is |
| partial: it may be missing fields and/or have them declared out of order. |
| This declaration will be corrected by the compiler. (But note that you |
| can only access fields that you declared, not others.) Any ``struct`` |
| declaration which doesn't use "``...``" is assumed to be exact, but this is |
| checked: you get an error if it is not correct. |
| |
| * integer types: the syntax "``typedef |
| int... foo_t;``" declares the type ``foo_t`` as an integer type |
| whose exact size and signedness is not specified. The compiler will |
| figure it out. (Note that this requires ``set_source()``; it does |
| not work with ``verify()``.) The ``int...`` can be replaced with |
| ``long...`` or ``unsigned long long...`` or any other primitive |
| integer type, with no effect. The type will always map to one of |
| ``(u)int(8,16,32,64)_t`` in Python, but in the generated C code, |
| only ``foo_t`` is used. |
| |
| * *New in version 1.3:* floating-point types: "``typedef |
| float... foo_t;``" (or equivalently "``typedef double... foo_t;``") |
| declares ``foo_t`` as a-float-or-a-double; the compiler will figure |
| out which it is. Note that if the actual C type is even larger |
| (``long double`` on some platforms), then compilation will fail. |
| The problem is that the Python "float" type cannot be used to store |
| the extra precision. (Use the non-dot-dot-dot syntax ``typedef long |
| double foo_t;`` as usual, which returns values that are not Python |
| floats at all but cdata "long double" objects.) |
| |
| * unknown types: the syntax "``typedef ... foo_t;``" declares the type |
| ``foo_t`` as opaque. Useful mainly for when the API takes and returns |
| ``foo_t *`` without you needing to look inside the ``foo_t``. Also |
| works with "``typedef ... *foo_p;``" which declares the pointer type |
| ``foo_p`` without giving a name to the opaque type itself. Note that |
| such an opaque struct has no known size, which prevents some operations |
| from working (mostly like in C). *You cannot use this syntax to |
| declare a specific type, like an integer type! It declares opaque |
| struct-like types only.* In some cases you need to say that |
| ``foo_t`` is not opaque, but just a struct where you don't know any |
| field; then you would use "``typedef struct { ...; } foo_t;``". |
| |
| * array lengths: when used as structure fields or in global variables, |
| arrays can have an unspecified length, as in "``int n[...];``". The |
| length is completed by the C compiler. |
| This is slightly different from "``int n[];``", because the latter |
| means that the length is not known even to the C compiler, and thus |
| no attempt is made to complete it. This supports |
| multidimensional arrays: "``int n[...][...];``". |
| |
| *New in version 1.2:* "``int m[][...];``", i.e. ``...`` can be used |
| in the innermost dimensions without being also used in the outermost |
| dimension. In the example given, the length of the ``m`` array is |
| assumed not to be known to the C compiler, but the length of every |
| item (like the sub-array ``m[0]``) is always known the C compiler. |
| In other words, only the outermost dimension can be specified as |
| ``[]``, both in C and in CFFI, but any dimension can be given as |
| ``[...]`` in CFFI. |
| |
| * enums: if you don't know the exact order (or values) of the declared |
| constants, then use this syntax: "``enum foo { A, B, C, ... };``" |
| (with a trailing "``...``"). The C compiler will be used to figure |
| out the exact values of the constants. An alternative syntax is |
| "``enum foo { A=..., B, C };``" or even |
| "``enum foo { A=..., B=..., C=... };``". Like |
| with structs, an ``enum`` without "``...``" is assumed to |
| be exact, and this is checked. |
| |
| * integer constants and macros: you can write in the ``cdef`` the line |
| "``#define FOO ...``", with any macro name FOO but with ``...`` as |
| a value. Provided the macro |
| is defined to be an integer value, this value will be available via |
| an attribute of the library object. The |
| same effect can be achieved by writing a declaration |
| ``static const int FOO;``. The latter is more general because it |
| supports other types than integer types (note: the C syntax is then |
| to write the ``const`` together with the variable name, as in |
| ``static char *const FOO;``). |
| |
| Currently, it is not supported to find automatically which of the |
| various integer or float types you need at which place---except in the |
| following case: if such a type is explicitly named. For an integer |
| type, use ``typedef int... the_type_name;``, or another type like |
| ``typedef unsigned long... the_type_name;``. Both are equivalent and |
| replaced by the real C type, which must be an integer type. |
| Similarly, for floating-point types, use ``typedef float... |
| the_type_name;`` or equivalently ``typedef double... the_type_name;``. |
| Note that ``long double`` cannot be detected this way. |
| |
| In the case of function arguments or return types, when it is a simple |
| integer/float type, you can simply misdeclare it. If you misdeclare a |
| function ``void f(long)`` as ``void f(int)``, it still works (but you |
| have to call it with arguments that fit an int). It works because the C |
| compiler will do the casting for us. This C-level casting of arguments |
| and return types only works for regular function, and not for function |
| pointer types; currently, it also does not work for variadic functions. |
| |
| For more complex types, you have no choice but be precise. For example, |
| you cannot misdeclare a ``int *`` argument as ``long *``, or a global |
| array ``int a[5];`` as ``long a[5];``. CFFI considers `all types listed |
| above`_ as primitive (so ``long long a[5];`` and ``int64_t a[5]`` are |
| different declarations). The reason for that is detailed in `a comment |
| about an issue.`__ |
| |
| .. __: https://bitbucket.org/cffi/cffi/issues/265/cffi-doesnt-allow-creating-pointers-to#comment-28406958 |
| |
| |
| ffibuilder.compile() etc.: compiling out-of-line modules |
| -------------------------------------------------------- |
| |
| You can use one of the following functions to actually generate the |
| .py or .c file prepared with ``ffibuilder.set_source()`` and |
| ``ffibuilder.cdef()``. |
| |
| Note that these function won't overwrite a .py/.c file with exactly |
| the same content, to preserve the mtime. In some cases where you need |
| the mtime to be updated anyway, delete the file before calling the |
| functions. |
| |
| *New in version 1.8:* the C code produced by ``emit_c_code()`` or |
| ``compile()`` contains ``#define Py_LIMITED_API``. This means that on |
| CPython >= 3.2, compiling this source produces a binary .so/.dll that |
| should work for any version of CPython >= 3.2 (as opposed to only for |
| the same version of CPython x.y). However, the standard ``distutils`` |
| package will still produce a file called e.g. |
| ``NAME.cpython-35m-x86_64-linux-gnu.so``. You can manually rename it to |
| ``NAME.abi3.so``, or use setuptools version 26 or later. Also, note |
| that compiling with a debug version of Python will not actually define |
| ``Py_LIMITED_API``, as doing so makes ``Python.h`` unhappy. |
| |
| *New in version 1.12:* ``Py_LIMITED_API`` is now defined on Windows too. |
| If you use ``virtualenv``, you need a recent version of it: versions |
| older than 16.0.0 forgot to copy ``python3.dll`` into the virtual |
| environment. In case upgrading ``virtualenv`` is a real problem, you |
| can manually edit the C code to remove the first line ``# define |
| Py_LIMITED_API``. |
| |
| **ffibuilder.compile(tmpdir='.', verbose=False, debug=None):** |
| explicitly generate the .py or .c file, |
| and (if .c) compile it. The output file is (or are) put in the |
| directory given by ``tmpdir``. In the examples given here, we use |
| ``if __name__ == "__main__": ffibuilder.compile()`` in the build scripts---if |
| they are directly executed, this makes them rebuild the .py/.c file in |
| the current directory. (Note: if a package is specified in the call |
| to ``set_source()``, then a corresponding subdirectory of the ``tmpdir`` |
| is used.) |
| |
| *New in version 1.4:* ``verbose`` argument. If True, it prints the |
| usual distutils output, including the command lines that call the |
| compiler. (This parameter might be changed to True by default in a |
| future release.) |
| |
| *New in version 1.8.1:* ``debug`` argument. If set to a bool, it |
| controls whether the C code is compiled in debug mode or not. The |
| default None means to use the host Python's ``sys.flags.debug``. |
| Starting with version 1.8.1, if you are running a debug-mode Python, the |
| C code is thus compiled in debug mode by default (note that it is anyway |
| necessary to do so on Windows). |
| |
| **ffibuilder.emit_python_code(filename):** generate the given .py file (same |
| as ``ffibuilder.compile()`` for ABI mode, with an explicitly-named file to |
| write). If you choose, you can include this .py file pre-packaged in |
| your own distributions: it is identical for any Python version (2 or |
| 3). |
| |
| **ffibuilder.emit_c_code(filename):** generate the given .c file (for API |
| mode) without compiling it. Can be used if you have some other method |
| to compile it, e.g. if you want to integrate with some larger build |
| system that will compile this file for you. You can also distribute |
| the .c file: unless the build script you used depends on the OS or |
| platform, the .c file itself is generic (it would be exactly the same |
| if produced on a different OS, with a different version of CPython, or |
| with PyPy; it is done with generating the appropriate ``#ifdef``). |
| |
| **ffibuilder.distutils_extension(tmpdir='build', verbose=True):** for |
| distutils-based ``setup.py`` files. Calling this creates the .c file |
| if needed in the given ``tmpdir``, and returns a |
| ``distutils.core.Extension`` instance. |
| |
| For Setuptools, you use instead the line |
| ``cffi_modules=["path/to/foo_build.py:ffibuilder"]`` in ``setup.py``. This |
| line asks Setuptools to import and use a helper provided by CFFI, |
| which in turn executes the file ``path/to/foo_build.py`` (as with |
| ``execfile()``) and looks up its global variable called ``ffibuilder``. You |
| can also say ``cffi_modules=["path/to/foo_build.py:maker"]``, where |
| ``maker`` names a global function; it is called with no argument and |
| is supposed to return a ``FFI`` object. |
| |
| |
| ffi/ffibuilder.include(): combining multiple CFFI interfaces |
| ------------------------------------------------------------ |
| |
| **ffi/ffibuilder.include(other_ffi)**: includes the typedefs, structs, unions, |
| enums and constants defined in another FFI instance. This is meant |
| for large projects where one CFFI-based interface depends on some |
| types declared in a different CFFI-based interface. |
| |
| *Note that you should only use one ffi object per library; the intended |
| usage of ffi.include() is if you want to interface with several |
| inter-dependent libraries.* For only one library, make one ``ffi`` |
| object. (You can write several ``cdef()`` calls over the same ``ffi`` |
| from several Python files, if one file would be too large.) |
| |
| For out-of-line modules, the ``ffibuilder.include(other_ffibuilder)`` |
| line should |
| occur in the build script, and the ``other_ffibuilder`` argument should be |
| another FFI instance that comes from another build script. When the two build |
| scripts are turned into generated files, say ``_ffi.so`` and |
| ``_other_ffi.so``, then importing ``_ffi.so`` will internally cause |
| ``_other_ffi.so`` to be imported. At that point, the real |
| declarations from ``_other_ffi.so`` are combined with the real |
| declarations from ``_ffi.so``. |
| |
| The usage of ``ffi.include()`` is the cdef-level equivalent of a |
| ``#include`` in C, where a part of the program might include types and |
| functions defined in another part for its own usage. You can see on |
| the ``ffi`` object (and associated ``lib`` objects on the *including* |
| side) the types and constants declared on the included side. In API |
| mode, you can also see the functions and global variables directly. |
| In ABI mode, these must be accessed via the original ``other_lib`` |
| object returned by the ``dlopen()`` method on ``other_ffi``. |
| |
| |
| ffi.cdef() limitations |
| ---------------------- |
| |
| All of the ANSI C *declarations* should be supported in ``cdef()``, |
| and some of C99. (This excludes any ``#include`` or ``#ifdef``.) |
| Known missing features that are either in C99, or are GCC or MSVC |
| extensions: |
| |
| * Any ``__attribute__`` or ``#pragma pack(n)`` |
| |
| * Additional types: special-size floating and fixed |
| point types, vector types, and so on. |
| |
| * The C99 types ``float _Complex`` and ``double _Complex`` are supported |
| by cffi since version 1.11, but not libffi: you cannot call C |
| functions with complex arguments or return value, except if they are |
| directly API-mode functions. The type ``long double _Complex`` is not |
| supported at all (declare and use it as if it were an array of two |
| ``long double``, and write wrapper functions in C with set_source()). |
| |
| * ``__restrict__`` or ``__restrict`` are extensions of, respectively, |
| GCC and MSVC. They are not recognized. But ``restrict`` is a C |
| keyword and is accepted (and ignored). |
| |
| Note that declarations like ``int field[];`` in |
| structures are interpreted as variable-length structures. Declarations |
| like ``int field[...];`` on the other hand are arrays whose length is |
| going to be completed by the compiler. You can use ``int field[];`` |
| for array fields that are not, in fact, variable-length; it works too, |
| but in this case, as CFFI |
| believes it cannot ask the C compiler for the length of the array, you |
| get reduced safety checks: for example, you risk overwriting the |
| following fields by passing too many array items in the constructor. |
| |
| *New in version 1.2:* |
| Thread-local variables (``__thread``) can be accessed, as well as |
| variables defined as dynamic macros (``#define myvar (*fetchme())``). |
| Before version 1.2, you need to write getter/setter functions. |
| |
| Note that if you declare a variable in ``cdef()`` without using |
| ``const``, CFFI assumes it is a read-write variable and generates two |
| pieces of code, one to read it and one to write it. If the variable |
| cannot in fact be written to in C code, for one reason or another, it |
| will not compile. In this case, you can declare it as a constant: for |
| example, instead of ``foo_t *myglob;`` you would use ``foo_t *const |
| myglob;``. Note also that ``const foo_t *myglob;`` is a *variable;* it |
| contains a variable pointer to a constant ``foo_t``. |
| |
| |
| Debugging dlopen'ed C libraries |
| ------------------------------- |
| |
| A few C libraries are actually hard to use correctly in a ``dlopen()`` |
| setting. This is because most C libraries are intended for, and tested |
| with, a situation where they are *linked* with another program, using |
| either static linking or dynamic linking --- but from a program written |
| in C, at start-up, using the linker's capabilities instead of |
| ``dlopen()``. |
| |
| This can occasionally create issues. You would have the same issues in |
| another setting than CFFI, like with ``ctypes`` or even plain C code that |
| calls ``dlopen()``. This section contains a few generally useful |
| environment variables (on Linux) that can help when debugging these |
| issues. |
| |
| **export LD_TRACE_LOADED_OBJECTS=all** |
| |
| provides a lot of information, sometimes too much depending on the |
| setting. Output verbose debugging information about the dynamic |
| linker. If set to ``all`` prints all debugging information it has, if |
| set to ``help`` prints a help message about which categories can be |
| specified in this environment variable |
| |
| **export LD_VERBOSE=1** |
| |
| (glibc since 2.1) If set to a nonempty string, output symbol |
| versioning information about the program if querying information |
| about the program (i.e., either ``LD_TRACE_LOADED_OBJECTS`` has been set, |
| or ``--list`` or ``--verify`` options have been given to the dynamic |
| linker). |
| |
| **export LD_WARN=1** |
| |
| (ELF only)(glibc since 2.1.3) If set to a nonempty string, warn |
| about unresolved symbols. |
| |
| |
| ffi.verify(): in-line API-mode |
| ------------------------------ |
| |
| **ffi.verify()** is supported for backward compatibility, but is |
| deprecated. ``ffi.verify(c_header_source, tmpdir=.., ext_package=.., |
| modulename=.., flags=.., **kwargs)`` makes and compiles a C file from |
| the ``ffi.cdef()``, like ``ffi.set_source()`` in API mode, and then |
| immediately loads and returns the dynamic library object. Some |
| non-trivial logic is used to decide if the dynamic library must be |
| recompiled or not; see below for ways to control it. |
| |
| The ``c_header_source`` and the extra keyword arguments have the |
| same meaning as in ``ffi.set_source()``. |
| |
| One remaining use case for ``ffi.verify()`` would be the following |
| hack to find explicitly the size of any type, in bytes, and have it |
| available in Python immediately (e.g. because it is needed in order to |
| write the rest of the build script): |
| |
| .. code-block:: python |
| |
| ffi = cffi.FFI() |
| ffi.cdef("const int mysize;") |
| lib = ffi.verify("const int mysize = sizeof(THE_TYPE);") |
| print lib.mysize |
| |
| Extra arguments to ``ffi.verify()``: |
| |
| * ``tmpdir`` controls where the C |
| files are created and compiled. Unless the ``CFFI_TMPDIR`` environment |
| variable is set, the default is |
| ``directory_containing_the_py_file/__pycache__`` using the |
| directory name of the .py file that contains the actual call to |
| ``ffi.verify()``. (This is a bit of a hack but is generally |
| consistent with the location of the .pyc files for your library. |
| The name ``__pycache__`` itself comes from Python 3.) |
| |
| * ``ext_package`` controls in which package the |
| compiled extension module should be looked from. This is |
| only useful after distributing ffi.verify()-based modules. |
| |
| * The ``tag`` argument gives an extra string inserted in the |
| middle of the extension module's name: ``_cffi_<tag>_<hash>``. |
| Useful to give a bit more context, e.g. when debugging. |
| |
| * The ``modulename`` argument can be used to force a specific module |
| name, overriding the name ``_cffi_<tag>_<hash>``. Use with care, |
| e.g. if you are passing variable information to ``verify()`` but |
| still want the module name to be always the same (e.g. absolute |
| paths to local files). In this case, no hash is computed and if |
| the module name already exists it will be reused without further |
| check. Be sure to have other means of clearing the ``tmpdir`` |
| whenever you change your sources. |
| |
| * ``source_extension`` has the same meaning as in ``ffibuilder.set_source()``. |
| |
| * The optional ``flags`` argument (ignored on Windows) defaults to |
| ``ffi.RTLD_NOW``; see ``man dlopen``. (With |
| ``ffibuilder.set_source()``, you would use ``sys.setdlopenflags()``.) |
| |
| * The optional ``relative_to`` argument is useful if you need to list |
| local files passed to the C compiler:: |
| |
| ext = ffi.verify(..., sources=['foo.c'], relative_to=__file__) |
| |
| The line above is roughly the same as:: |
| |
| ext = ffi.verify(..., sources=['/path/to/this/file/foo.c']) |
| |
| except that the default name of the produced library is built from |
| the CRC checkum of the argument ``sources``, as well as most other |
| arguments you give to ``ffi.verify()`` -- but not ``relative_to``. |
| So if you used the second line, it would stop finding the |
| already-compiled library after your project is installed, because |
| the ``'/path/to/this/file'`` suddenly changed. The first line does |
| not have this problem. |
| |
| Note that during development, every time you change the C sources that |
| you pass to ``cdef()`` or ``verify()``, then the latter will create a |
| new module file name, based on two CRC32 hashes computed from these |
| strings. This creates more and more files in the ``__pycache__`` |
| directory. It is recommended that you clean it up from time to time. |
| A nice way to do that is to add, in your test suite, a call to |
| ``cffi.verifier.cleanup_tmpdir()``. Alternatively, you can manually |
| remove the whole ``__pycache__`` directory. |
| |
| An alternative cache directory can be given as the ``tmpdir`` argument |
| to ``verify()``, via the environment variable ``CFFI_TMPDIR``, or by |
| calling ``cffi.verifier.set_tmpdir(path)`` prior to calling |
| ``verify``. |
| |
| |
| Upgrading from CFFI 0.9 to CFFI 1.0 |
| ----------------------------------- |
| |
| CFFI 1.0 is backward-compatible, but it is still a good idea to |
| consider moving to the out-of-line approach new in 1.0. Here are the |
| steps. |
| |
| **ABI mode** if your CFFI project uses ``ffi.dlopen()``: |
| |
| .. code-block:: python |
| |
| import cffi |
| |
| ffi = cffi.FFI() |
| ffi.cdef("stuff") |
| lib = ffi.dlopen("libpath") |
| |
| and *if* the "stuff" part is big enough that import time is a concern, |
| then rewrite it as described in `the out-of-line but still ABI mode`__ |
| above. Optionally, see also the `setuptools integration`__ paragraph. |
| |
| .. __: out-of-line-abi_ |
| .. __: distutils-setuptools_ |
| |
| |
| **API mode** if your CFFI project uses ``ffi.verify()``: |
| |
| .. code-block:: python |
| |
| import cffi |
| |
| ffi = cffi.FFI() |
| ffi.cdef("stuff") |
| lib = ffi.verify("real C code") |
| |
| then you should really rewrite it as described in `the out-of-line, |
| API mode`__ above. It avoids a number of issues that have caused |
| ``ffi.verify()`` to grow a number of extra arguments over time. Then |
| see the `distutils or setuptools`__ paragraph. Also, remember to |
| remove the ``ext_package=".."`` from your ``setup.py``, which was |
| sometimes needed with ``verify()`` but is just creating confusion with |
| ``set_source()``. |
| |
| .. __: out-of-line-api_ |
| .. __: distutils-setuptools_ |
| |
| The following example should work both with old (pre-1.0) and new |
| versions of CFFI---supporting both is important to run on old |
| versions of PyPy (CFFI 1.0 does not work in PyPy < 2.6): |
| |
| .. code-block:: python |
| |
| # in a separate file "package/foo_build.py" |
| import cffi |
| |
| ffi = cffi.FFI() |
| C_HEADER_SRC = r''' |
| #include "somelib.h" |
| ''' |
| C_KEYWORDS = dict(libraries=['somelib']) |
| |
| if hasattr(ffi, 'set_source'): |
| ffi.set_source("package._foo", C_HEADER_SRC, **C_KEYWORDS) |
| |
| ffi.cdef(''' |
| int foo(int); |
| ''') |
| |
| if __name__ == "__main__": |
| ffi.compile() |
| |
| And in the main program: |
| |
| .. code-block:: python |
| |
| try: |
| from package._foo import ffi, lib |
| except ImportError: |
| from package.foo_build import ffi, C_HEADER_SRC, C_KEYWORDS |
| lib = ffi.verify(C_HEADER_SRC, **C_KEYWORDS) |
| |
| (FWIW, this latest trick can be used more generally to allow the |
| import to "work" even if the ``_foo`` module was not generated.) |
| |
| Writing a ``setup.py`` script that works both with CFFI 0.9 and 1.0 |
| requires explicitly checking the version of CFFI that we can have---it |
| is hard-coded as a built-in module in PyPy: |
| |
| .. code-block:: python |
| |
| if '_cffi_backend' in sys.builtin_module_names: # PyPy |
| import _cffi_backend |
| requires_cffi = "cffi==" + _cffi_backend.__version__ |
| else: |
| requires_cffi = "cffi>=1.0.0" |
| |
| Then we use the ``requires_cffi`` variable to give different arguments to |
| ``setup()`` as needed, e.g.: |
| |
| .. code-block:: python |
| |
| if requires_cffi.startswith("cffi==0."): |
| # backward compatibility: we have "cffi==0.*" |
| from package.foo_build import ffi |
| extra_args = dict( |
| ext_modules=[ffi.verifier.get_extension()], |
| ext_package="...", # if needed |
| ) |
| else: |
| extra_args = dict( |
| setup_requires=[requires_cffi], |
| cffi_modules=['package/foo_build.py:ffi'], |
| ) |
| setup( |
| name=..., |
| ..., |
| install_requires=[requires_cffi], |
| **extra_args |
| ) |