Author: Armin Rigo <ar...@tunes.org>
Branch: static-callback-embedding
Changeset: r2579:7d0c3632fe95
Date: 2016-01-14 10:13 +0100
http://bitbucket.org/cffi/cffi/changeset/7d0c3632fe95/

Log:    Add some sections

diff --git a/doc/source/embedding.rst b/doc/source/embedding.rst
--- a/doc/source/embedding.rst
+++ b/doc/source/embedding.rst
@@ -24,6 +24,12 @@
   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.
+
+.. note:: PyPy release 4.0.1 contains CFFI 1.4 only.
+
 This is entirely *new in version 1.5.*
 
 
@@ -163,6 +169,9 @@
 * ``@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
@@ -199,11 +208,82 @@
 
 .. __: using.html#working
 .. __: using.html#def-extern
+.. __: using.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.
+
+
+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 ``ffi.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 included with the
+DLL is executed the first time such a call is done.
+
+
 Embedding and Extending
 -----------------------
 
diff --git a/doc/source/using.rst b/doc/source/using.rst
--- a/doc/source/using.rst
+++ b/doc/source/using.rst
@@ -423,6 +423,7 @@
 with ``int foo();`` really means ``int foo(void);``.)
 
 
+.. _extern-python:
 .. _`extern "Python"`:
 
 Extern "Python" (new-style callbacks)
@@ -1069,12 +1070,13 @@
 points in time, and using it in a ``with`` statement.
 
 
+.. _ffi-new_handle:
 .. _`ffi.new_handle()`:
 
 **ffi.new_handle(python_object)**: return a non-NULL cdata of type
 ``void *`` that contains an opaque reference to ``python_object``.  You
 can pass it around to C functions or store it into C structures.  Later,
-you can use **ffi.from_handle(p)** to retrive the original
+you can use **ffi.from_handle(p)** to retrieve the original
 ``python_object`` from a value with the same ``void *`` pointer.
 *Calling ffi.from_handle(p) is invalid and will likely crash if
 the cdata object returned by new_handle() is not kept alive!*
_______________________________________________
pypy-commit mailing list
pypy-commit@python.org
https://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to