[pypy-commit] cffi static-callback-embedding: more doc
arigo
pypy.commits at gmail.com
Wed Jan 13 07:30:34 EST 2016
Author: Armin Rigo <arigo at tunes.org>
Branch: static-callback-embedding
Changeset: r2575:084db6ef07fc
Date: 2016-01-13 13:30 +0100
http://bitbucket.org/cffi/cffi/changeset/084db6ef07fc/
Log: more doc
diff --git a/doc/source/cdef.rst b/doc/source/cdef.rst
--- a/doc/source/cdef.rst
+++ b/doc/source/cdef.rst
@@ -138,6 +138,8 @@
for ``lib.__class__`` before version 1.4.
+.. _cdef:
+
ffi.cdef(): declaring types and functions
-----------------------------------------
diff --git a/doc/source/embedding.rst b/doc/source/embedding.rst
--- a/doc/source/embedding.rst
+++ b/doc/source/embedding.rst
@@ -77,3 +77,93 @@
standard library ``distutils`` package, which is really developed
and tested for the purpose of making CPython extension modules, not
other DLLs.
+
+
+More reading
+------------
+
+(XXX should point to a few places in the rest of the CFFI docs where
+people starting from embedding would like to go next)
+
+XXX copy the content of ffi.embedding() to a .h
+
+
+Embedding and Extending
+-----------------------
+
+The embedding mode is not incompatible with the non-embedding mode of
+CFFI. The Python code can import not only ``ffi`` but also ``lib``
+from the module you define. This ``lib`` contains all the C symbols
+that are available to Python. This includes all functions and global
+variables declared in ``ffi.embedding_api()`` (it is how you should
+read/write the global variables from Python).
+
+But you can use ``ffi.cdef()`` *in addition to*
+``ffi.embedding_api()`` to exchange more C functions and global
+variables between C and Python, without also making them exports of
+the DLL. See `here for more about cdef.`__
+
+.. __: cdef.html#cdef
+
+``ffi.cdef()`` is used to access functions and variables that you can,
+and should, define as ``static`` in ``set_source()``. On the other
+hand, the C functions declared with ``ffi.embedding_api()`` work
+similarly to ``extern "Python"`` functions from ``ffi.cdef()``.
+See `here for more about extern "Python".`__ See `here for details
+about @ffi.def_extern().`__
+
+.. __: using.html#extern-python
+.. __: using.html#extern-python-ref
+
+In some cases, you want to write a DLL-exported C function in C
+directly, maybe to handle some cases before calling Python functions.
+To do that, you must *not* write the function's signature in
+``ffi.embedding_api()``. You must only write the custom function
+definition in ``ffi.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" (technically a call from C to Python,
+although in this case it is not calling anything back): you need a
+``ffi.cdef()`` with "``extern "Python" int mycb(int);``", and then you
+can write this in ``ffi.set_source()``:
+
+.. code-block:: c
+
+ 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 at this
+time, if it happens that ``mycb()`` is the first function called
+from C. (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 ``ffi.embedding_api()``
+actually implements function calls that directly invoke Python code;
+we have merely decomposed it explicitly, in order to add some custom C
+code in the middle.
diff --git a/doc/source/using.rst b/doc/source/using.rst
--- a/doc/source/using.rst
+++ b/doc/source/using.rst
@@ -603,6 +603,9 @@
}
""")
+
+.. _extern-python-ref:
+
Extern "Python": reference
~~~~~~~~~~~~~~~~~~~~~~~~~~
More information about the pypy-commit
mailing list