================================
Using CFFI for embedding
================================

.. contents::

You can use CFFI to generate C code which exports the API of your choice
to any C application that wants to link with this C code.  This API,
which you define yourself, ends up as the API of a ``.so/.dll/.dylib``
library---or you can statically link it within a larger application.

Possible use cases:

* Exposing a library written in Python directly to C/C++ programs.

* Using Python to make a "plug-in" for an existing C/C++ program that is
  already written to load them.

* Using Python to implement part of a larger C/C++ application (with
  static linking).

* Writing a small C/C++ wrapper around Python, hiding the fact that the
  application is actually written in Python (to make a custom
  command-line interface; for distribution purposes; or simply to make
  it a bit harder to reverse-engineer the application).

The general idea is as follows:

* You write and execute a Python script, which produces a ``.c`` file
  with the API of your choice (and optionally compile it into a
  ``.so/.dll/.dylib``).  The script also gives some Python code to be
  "frozen" inside the ``.so``.

* At runtime, the C application loads this ``.so/.dll/.dylib`` (or is
  statically linked with the ``.c`` source) without having to know that
  it was produced from Python and CFFI.

* The first time a C function is called, Python is initialized and
  the frozen Python code is executed.

* The frozen Python code defines more Python functions that implement the
  C functions of your API, which are then used for all subsequent C
  function calls.

One of the goals of this approach is to be entirely independent from
the CPython C API: no ``Py_Initialize()`` nor ``PyRun_SimpleString()``
nor even ``PyObject``.  It works identically on CPython and PyPy.

This is entirely *new in version 1.5.*  (PyPy contains CFFI 1.5 since
release 5.0.)


Usage
-----

.. __: overview.html#embedding

See the `paragraph in the overview page`__ for a quick introduction.
In this section, we explain every step in more details.  We will use
here this slightly expanded example:

.. code-block:: c

    /* file plugin.h */
    typedef struct { int x, y; } point_t;
    extern int do_stuff(point_t *);

.. code-block:: c

    /* file plugin.h, Windows-friendly version */
    typedef struct { int x, y; } point_t;

    /* When including this file from ffibuilder.set_source(), the
       following macro is defined to '__declspec(dllexport)'.  When
       including this file directly from your C program, we define
       it to 'extern __declspec(dllimport)' instead.

       With non-MSVC compilers we simply define it to 'extern'.
       (The 'extern' is needed for sharing global variables;
       functions would be fine without it.  The macros always
       include 'extern': you must not repeat it when using the
       macros later.)
    */
    #ifndef CFFI_DLLEXPORT
    #  if defined(_MSC_VER)
    #    define CFFI_DLLEXPORT  extern __declspec(dllimport)
    #  else
    #    define CFFI_DLLEXPORT  extern
    #  endif
    #endif

    CFFI_DLLEXPORT int do_stuff(point_t *);

.. code-block:: python

    # file plugin_build.py
    import cffi
    ffibuilder = cffi.FFI()

    with open('plugin.h') as f:
        # read plugin.h and pass it to embedding_api(), manually
        # removing the '#' directives and the CFFI_DLLEXPORT
        data = ''.join([line for line in f if not line.startswith('#')])
        data = data.replace('CFFI_DLLEXPORT', '')
        ffibuilder.embedding_api(data)

    ffibuilder.set_source("my_plugin", r'''
        #include "plugin.h"
    ''')

    ffibuilder.embedding_init_code("""
        from my_plugin import ffi

        @ffi.def_extern()
        def do_stuff(p):
            print("adding %d and %d" % (p.x, p.y))
            return p.x + p.y
    """)

    ffibuilder.compile(target="plugin-1.5.*", verbose=True)
    # or: ffibuilder.emit_c_code("my_plugin.c")

Running the code above produces a *DLL*, i,e, a dynamically-loadable
library.  It is a file with the extension ``.dll`` on Windows,
``.dylib`` on Mac OS/X, or ``.so`` on other platforms.  As usual, it
is produced by generating some intermediate ``.c`` code and then
calling the regular platform-specific C compiler.  See below__ for
some pointers to C-level issues with using the produced library.

.. __: `Issues about using the .so`_

Here are some details about the methods used above:

* **ffibuilder.embedding_api(source):** parses the given C source, which
  declares functions that you want to be exported by the DLL.  It can
  also declare types, constants and global variables that are part of
  the C-level API of your DLL.

  The functions that are found in ``source`` will be automatically
  defined in the ``.c`` file: they will contain code that initializes
  the Python interpreter the first time any of them is called,
  followed by code to call the attached Python function (with
  ``@ffi.def_extern()``, see next point).

  The global variables, on the other hand, are not automatically
  produced.  You have to write their definition explicitly in
  ``ffibuilder.set_source()``, as regular C code (see the point after next).

* **ffibuilder.embedding_init_code(python_code):** this gives
  initialization-time Python source code.  This code is copied
  ("frozen") inside the DLL.  At runtime, the code is executed when
  the DLL is first initialized, just after Python itself is
  initialized.  This newly initialized Python interpreter has got an
  extra "built-in" module that can be loaded magically without
  accessing any files, with a line like "``from my_plugin import ffi,
  lib``".  The name ``my_plugin`` comes from the first argument to
  ``ffibuilder.set_source()``.  This module represents "the caller's C world"
  from the point of view of Python.

  The initialization-time Python code can import other modules or
  packages as usual.  You may have typical Python issues like needing
  to set up ``sys.path`` somehow manually first.

  For every function declared within ``ffibuilder.embedding_api()``, the
  initialization-time Python code or one of the modules it imports
  should use the decorator ``@ffi.def_extern()`` to attach a
  corresponding Python function to it.

  If the initialization-time Python code fails with an exception, then
  you get a traceback printed to stderr, along with more information
  to help you identify problems like wrong ``sys.path``.  If some
  function remains unattached at the time where the C code tries to
  call it, an error message is also printed to stderr and the function
  returns zero/null.

  Note that the CFFI module never calls ``exit()``, but CPython itself
  contains code that calls ``exit()``, for example if importing
  ``site`` fails.  This may be worked around in the future.

* **ffibuilder.set_source(c_module_name, c_code):** set the name of the
  module from Python's point of view.  It also gives more C code which
  will be included in the generated C code.  In trivial examples it
  can be an empty string.  It is where you would ``#include`` some
  other files, define global variables, and so on.  The macro
  ``CFFI_DLLEXPORT`` is available to this C code: it expands to the
  platform-specific way of saying "the following declaration should be
  exported from the DLL".  For example, you would put "``extern int
  my_glob;``" in ``ffibuilder.embedding_api()`` and "``CFFI_DLLEXPORT int
  my_glob = 42;``" in ``ffibuilder.set_source()``.

  Currently, any *type* declared in ``ffibuilder.embedding_api()`` must also
  be present in the ``c_code``.  This is automatic if this code
  contains a line like ``#include "plugin.h"`` in the example above.

* **ffibuilder.compile([target=...] [, verbose=True]):** make the C code and
  compile it.  By default, it produces a file called
  ``c_module_name.dll``, ``c_module_name.dylib`` or
  ``c_module_name.so``, but the default can be changed with the
  optional ``target`` keyword argument.  You can use
  ``target="foo.*"`` with a literal ``*`` to ask for a file called
  ``foo.dll`` on Windows, ``foo.dylib`` on OS/X and ``foo.so``
  elsewhere.  One reason for specifying an alternate ``target`` is to
  include characters not usually allowed in Python module names, like
  "``plugin-1.5.*``".

  For more complicated cases, you can call instead
  ``ffibuilder.emit_c_code("foo.c")`` and compile the resulting ``foo.c``
  file using other means.  CFFI's compilation logic is based on the
  standard library ``distutils`` package, which is really developed
  and tested for the purpose of making CPython extension modules; it
  might not always be appropriate for making general DLLs.  Also, just
  getting the C code is what you need if you do not want to make a
  stand-alone ``.so/.dll/.dylib`` file: this C file can be compiled
  and statically linked as part of a larger application.


More reading
------------

If you're reading this page about embedding and you are not familiar
with CFFI already, here are a few pointers to what you could read
next:

* For the ``@ffi.def_extern()`` functions, integer C types are passed
  simply as Python integers; and simple pointers-to-struct and basic
  arrays are all straightforward enough.  However, sooner or later you
  will need to read about this topic in more details here__.

* ``@ffi.def_extern()``: see `documentation here,`__ notably on what
  happens if the Python function raises an exception.

* To create Python objects attached to C data, one common solution is
  to use ``ffi.new_handle()``.  See documentation here__.

* In embedding mode, the major direction is C code that calls Python
  functions.  This is the opposite of the regular extending mode of
  CFFI, in which the major direction is Python code calling C.  That's
  why the page `Using the ffi/lib objects`_ talks first about the
  latter, and why the direction "C code that calls Python" is
  generally referred to as "callbacks" in that page.  If you also
  need to have your Python code call C code, read more about
  `Embedding and Extending`_ below.

* ``ffibuilder.embedding_api(source)``: follows the same syntax as
  ``ffibuilder.cdef()``, `documented here.`__  You can use the "``...``"
  syntax as well, although in practice it may be less useful than it
  is for ``cdef()``.  On the other hand, it is expected that often the
  C sources that you need to give to ``ffibuilder.embedding_api()`` would be
  exactly the same as the content of some ``.h`` file that you want to
  give to users of your DLL.  That's why the example above does this::

      with open('foo.h') as f:
          ffibuilder.embedding_api(f.read())

  Note that a drawback of this approach is that ``ffibuilder.embedding_api()``
  doesn't support ``#ifdef`` directives.  You may have to use a more
  convoluted expression like::

      with open('foo.h') as f:
          lines = [line for line in f if not line.startswith('#')]
          ffibuilder.embedding_api(''.join(lines))

  As in the example above, you can also use the same ``foo.h`` from
  ``ffibuilder.set_source()``::

      ffibuilder.set_source('module_name', r'''
          #include "foo.h"
      ''')


.. __: using.html#working
.. __: using.html#def-extern
.. __: ref.html#ffi-new-handle
.. __: cdef.html#cdef

.. _`Using the ffi/lib objects`: using.html


Troubleshooting
---------------

* The error message

    cffi extension module 'c_module_name' has unknown version 0x2701

  means that the running Python interpreter located a CFFI version older
  than 1.5.  CFFI 1.5 or newer must be installed in the running Python.

* On PyPy, the error message

    debug: pypy_setup_home: directories 'lib-python' and 'lib_pypy' not
    found in pypy's shared library location or in any parent directory

  means that the ``libpypy-c.so`` file was found, but the standard library
  was not found from this location.  This occurs at least on some Linux
  distributions, because they put ``libpypy-c.so`` inside ``/usr/lib/``,
  instead of the way we recommend, which is: keep that file inside
  ``/opt/pypy/bin/`` and put a symlink to there from ``/usr/lib/``.
  The quickest fix is to do that change manually.


Issues about using the .so
--------------------------

This paragraph describes issues that are not necessarily specific to
CFFI.  It assumes that you have obtained the ``.so/.dylib/.dll`` file as
described above, but that you have troubles using it.  (In summary: it
is a mess.  This is my own experience, slowly built by using Google and
by listening to reports from various platforms.  Please report any
inaccuracies in this paragraph or better ways to do things.)

* The file produced by CFFI should follow this naming pattern:
  ``libmy_plugin.so`` on Linux, ``libmy_plugin.dylib`` on Mac, or
  ``my_plugin.dll`` on Windows (no ``lib`` prefix on Windows).

* First note that this file does not contain the Python interpreter
  nor the standard library of Python.  You still need it to be
  somewhere.  There are ways to compact it to a smaller number of files,
  but this is outside the scope of CFFI (please report if you used some
  of these ways successfully so that I can add some links here).

* In what we'll call the "main program", the ``.so`` can be either
  used dynamically (e.g. by calling ``dlopen()`` or ``LoadLibrary()``
  inside the main program), or at compile-time (e.g. by compiling it
  with ``gcc -lmy_plugin``).  The former case is always used if you're
  building a plugin for a program, and the program itself doesn't need
  to be recompiled.  The latter case is for making a CFFI library that
  is more tightly integrated inside the main program.

* In the case of compile-time usage: you can add the gcc
  option ``-Lsome/path/`` before ``-lmy_plugin`` to describe where the
  ``libmy_plugin.so`` is.  On some platforms, notably Linux, ``gcc``
  will complain if it can find ``libmy_plugin.so`` but not
  ``libpython27.so`` or ``libpypy-c.so``.  To fix it, you need to call
  ``LD_LIBRARY_PATH=/some/path/to/libpypy gcc``.

* When actually executing the main program, it needs to find the
  ``libmy_plugin.so`` but also ``libpython27.so`` or ``libpypy-c.so``.
  For PyPy, unpack a PyPy distribution and you get a full directory
  structure with ``libpypy-c.so`` inside a ``bin`` subdirectory, or on
  Windows ``pypy-c.dll`` inside the top directory; you must not move
  this file around, but just point to it.  One way to point to it is by
  running the main program with some environment variable:
  ``LD_LIBRARY_PATH=/some/path/to/libpypy`` on Linux,
  ``DYLD_LIBRARY_PATH=/some/path/to/libpypy`` on OS/X.

* You can avoid the ``LD_LIBRARY_PATH`` issue if you compile
  ``libmy_plugin.so`` with the path hard-coded inside in the first
  place.  On Linux, this is done by ``gcc -Wl,-rpath=/some/path``.  You
  would put this option in ``ffibuilder.set_source("my_plugin", ...,
  extra_link_args=['-Wl,-rpath=/some/path/to/libpypy'])``.  The path can
  start with ``$ORIGIN`` to mean "the directory where
  ``libmy_plugin.so`` is".  You can then specify a path relative to that
  place, like ``extra_link_args=['-Wl,-rpath=$ORIGIN/../venv/bin']``.
  Use ``ldd libmy_plugin.so`` to look at what path is currently compiled
  in after the expansion of ``$ORIGIN``.)

  After this, you don't need ``LD_LIBRARY_PATH`` any more to locate
  ``libpython27.so`` or ``libpypy-c.so`` at runtime.  In theory it
  should also cover the call to ``gcc`` for the main program.  I wasn't
  able to make ``gcc`` happy without ``LD_LIBRARY_PATH`` on Linux if
  the rpath starts with ``$ORIGIN``, though.

* The same rpath trick might be used to let the main program find
  ``libmy_plugin.so`` in the first place without ``LD_LIBRARY_PATH``.
  (This doesn't apply if the main program uses ``dlopen()`` to load it
  as a dynamic plugin.)  You'd make the main program with ``gcc
  -Wl,-rpath=/path/to/libmyplugin``, possibly with ``$ORIGIN``.  The
  ``$`` in ``$ORIGIN`` causes various shell problems on its own: if
  using a common shell you need to say ``gcc
  -Wl,-rpath=\$ORIGIN``.  From a Makefile, you need to say
  something like ``gcc -Wl,-rpath=\$$ORIGIN``.

* On some Linux distributions, notably Debian, the ``.so`` files of
  CPython C extension modules may be compiled without saying that they
  depend on ``libpythonX.Y.so``.  This makes such Python systems
  unsuitable for embedding if the embedder uses ``dlopen(...,
  RTLD_LOCAL)``.  You get an ``undefined symbol`` error.  See
  `issue #264`__.  A workaround is to first call
  ``dlopen("libpythonX.Y.so", RTLD_LAZY|RTLD_GLOBAL)``, which will
  force ``libpythonX.Y.so`` to be loaded first.

.. __: https://bitbucket.org/cffi/cffi/issues/264/


Using multiple CFFI-made DLLs
-----------------------------

Multiple CFFI-made DLLs can be used by the same process.

Note that all CFFI-made DLLs in a process share a single Python
interpreter.  The effect is the same as the one you get by trying to
build a large Python application by assembling a lot of unrelated
packages.  Some of these might be libraries that monkey-patch some
functions from the standard library, for example, which might be
unexpected from other parts.


Multithreading
--------------

Multithreading should work transparently, based on Python's standard
Global Interpreter Lock.

If two threads both try to call a C function when Python is not yet
initialized, then locking occurs.  One thread proceeds with
initialization and blocks the other thread.  The other thread will be
allowed to continue only when the execution of the initialization-time
Python code is done.

If the two threads call two *different* CFFI-made DLLs, the Python
initialization itself will still be serialized, but the two pieces of
initialization-time Python code will not.  The idea is that there is a
priori no reason for one DLL to wait for initialization of the other
DLL to be complete.

After initialization, Python's standard Global Interpreter Lock kicks
in.  The end result is that when one CPU progresses on executing
Python code, no other CPU can progress on executing more Python code
from another thread of the same process.  At regular intervals, the
lock switches to a different thread, so that no single thread should
appear to block indefinitely.


Testing
-------

For testing purposes, a CFFI-made DLL can be imported in a running
Python interpreter instead of being loaded like a C shared library.

You might have some issues with the file name: for example, on
Windows, Python expects the file to be called ``c_module_name.pyd``,
but the CFFI-made DLL is called ``target.dll`` instead.  The base name
``target`` is the one specified in ``ffibuilder.compile()``, and on Windows
the extension is ``.dll`` instead of ``.pyd``.  You have to rename or
copy the file, or on POSIX use a symlink.

The module then works like a regular CFFI extension module.  It is
imported with "``from c_module_name import ffi, lib``" and exposes on
the ``lib`` object all C functions.  You can test it by calling these
C functions.  The initialization-time Python code frozen inside the
DLL is executed the first time such a call is done.


Embedding and Extending
-----------------------

The embedding mode is not incompatible with the non-embedding mode of
CFFI.

You can use *both* ``ffibuilder.embedding_api()`` and
``ffibuilder.cdef()`` in the
same build script.  You put in the former the declarations you want to
be exported by the DLL; you put in the latter only the C functions and
types that you want to share between C and Python, but not export from
the DLL.

As an example of that, consider the case where you would like to have
a DLL-exported C function written in C directly, maybe to handle some
cases before calling Python functions.  To do that, you must *not* put
the function's signature in ``ffibuilder.embedding_api()``.  (Note that this
requires more hacks if you use ``ffibuilder.embedding_api(f.read())``.)
You must only write the custom function definition in
``ffibuilder.set_source()``, and prefix it with the macro CFFI_DLLEXPORT:

.. code-block:: c

    CFFI_DLLEXPORT int myfunc(int a, int b)
    {
        /* implementation here */
    }

This function can, if it wants, invoke Python functions using the
general mechanism of "callbacks"---called this way because it is a
call from C to Python, although in this case it is not calling
anything back:

.. code-block:: python

    ffibuilder.cdef("""
        extern "Python" int mycb(int);
    """)

    ffibuilder.set_source("my_plugin", r"""

        static int mycb(int);   /* the callback: forward declaration, to make
                                   it accessible from the C code that follows */

        CFFI_DLLEXPORT int myfunc(int a, int b)
        {
            int product = a * b;   /* some custom C code */
            return mycb(product);
        }
    """)

and then the Python initialization code needs to contain the lines:

.. code-block:: python

    @ffi.def_extern()
    def mycb(x):
        print "hi, I'm called with x =", x
        return x * 10

This ``@ffi.def_extern`` is attaching a Python function to the C
callback ``mycb()``, which in this case is not exported from the DLL.
Nevertheless, the automatic initialization of Python occurs when
``mycb()`` is called, if it happens to be the first function called
from C.  More precisely, it does not happen when ``myfunc()`` is
called: this is just a C function, with no extra code magically
inserted around it.  It only happens when ``myfunc()`` calls
``mycb()``.

As the above explanation hints, this is how ``ffibuilder.embedding_api()``
actually implements function calls that directly invoke Python code;
here, we have merely decomposed it explicitly, in order to add some
custom C code in the middle.

In case you need to force, from C code, Python to be initialized
before the first ``@ffi.def_extern()`` is called, you can do so by
calling the C function ``cffi_start_python()`` with no argument.  It
returns an integer, 0 or -1, to tell if the initialization succeeded
or not.  Currently there is no way to prevent a failing initialization
from also dumping a traceback and more information to stderr.
