[pypy-commit] cffi static-callback-embedding: more doc
arigo
pypy.commits at gmail.com
Wed Jan 13 06:35:32 EST 2016
Author: Armin Rigo <arigo at tunes.org>
Branch: static-callback-embedding
Changeset: r2574:3155fc3812ed
Date: 2016-01-13 12:35 +0100
http://bitbucket.org/cffi/cffi/changeset/3155fc3812ed/
Log: more doc
diff --git a/doc/source/embedding.rst b/doc/source/embedding.rst
--- a/doc/source/embedding.rst
+++ b/doc/source/embedding.rst
@@ -5,18 +5,17 @@
.. contents::
From *version 1.5,* you can use CFFI to generate a ``.so/.dll`` which
-is no longer usable only from Python, but which exports the API of
-your choice to any C application that wants to link with this
-``.so/.dll``.
+exports the API of your choice to any C application that wants to link
+with this ``.so/.dll``.
Usage
-----
See the `paragraph in the overview page`__ for a quick introduction.
-We decompose and explain every step below. We will call *DLL* the
-dynamically-loaded library that we are producing; it is a file with
-the (default) extension ``.dll`` on Windows or ``.so`` on other
+In this section, we explain every step in more details. We call *DLL*
+the dynamically-loaded library that we are producing; it is a file
+with the (default) extension ``.dll`` on Windows 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.
@@ -27,26 +26,54 @@
also declare types, constants and global variables that are part of
the C-level API of your DLL.
- The functions are automatically produced in the ``.c`` file: they
+ The functions are automatically defined in the ``.c`` file: they
contain code that initializes the Python interpreter the first time
- any of them is called, followed by code to call the associated
- Python function (see next point).
+ 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
- ``ffi.set_source()``, as regular C code. (The C code, as usual, can
- include an initializer, or define the missing length for ``int
- glob[];``, for example).
+ ``ffi.set_source()``, as regular C code.
-* **ffi.embedding_init_code(python_code):** this stores the given
- Python source code inside the DLL. This code will be executed at
- runtime when the DLL is first initialized, just after Python itself
- is initialized. This Python interpreter runs with the DLL ready
- to be imported as a xxxxxxxxxxxxxx
+* **ffi.embedding_init_code(python_code):** this gives
+ initialization-time Python source code. This code is copied 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 the DLL ready to be imported,
+ typically with a line like ``from module_name import ffi, lib``
+ (where ``module_name`` is the name given in first argument to
+ ``ffi.set_source()``).
+
+ This Python code can import other modules or packages as usual (it
+ might need to set up ``sys.path`` first). You should use the
+ decorator ``@ffi.def_extern()`` to attach a Python function to each
+ of the C functions declared within ``ffi.embedding_api()``. (If you
+ don't, calling the C function results for now in a message printed
+ to stderr and a zero return value.)
+
+* **ffi.set_source(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 simple 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 "``int
+ my_glob;``" in ``ffi.embedding_api()`` and "``CFFI_DLLEXPORT int
+ my_glob = 42;``" in ``ffi.set_source()``.
+* **ffi.compile([target=...] [, verbose=True]):** make the C code and
+ compile it. By default, it produces a file called
+ ``module_name.dll`` or ``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 or ``foo.so`` elsewhere. (The ``target``
+ file name can contain characters not usually allowed in Python
+ module names.)
- It should typically attach a Python function to each
- of the C functions declared in ``embedding_api()``. It does this
- by importing the ``ffi`` object from the
-
- with ``@ffi.def_extern()``.
+ For more complicated cases, you can call instead
+ ``ffi.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, not
+ other DLLs.
diff --git a/doc/source/overview.rst b/doc/source/overview.rst
--- a/doc/source/overview.rst
+++ b/doc/source/overview.rst
@@ -294,9 +294,9 @@
*New in version 1.5.*
-CFFI can also be used for embedding__, by creating a standard
-dynamically-linked library (``.dll`` under Windows, ``.so``
-elsewhere). This DLL can then be used from any C application.
+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
@@ -307,10 +307,10 @@
int do_stuff(int, int);
""")
- ffi.set_source("mystuff", "")
+ ffi.set_source("my_plugin", "")
ffi.embedding_init_code("""
- from mystuff import ffi
+ from my_plugin import ffi
@ffi.def_extern()
def do_stuff(x, y):
@@ -318,18 +318,18 @@
return x + y
""")
- ffi.compile(verbose=True)
+ ffi.compile(target="plugin-1.5.*", verbose=True)
-This simple example creates ``mystuff.dll`` or ``mystuff.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.`__
+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
More information about the pypy-commit
mailing list