Author: Armin Rigo <[email protected]>
Branch: 
Changeset: r2672:e127961f57ec
Date: 2016-04-21 11:45 +0200
http://bitbucket.org/cffi/cffi/changeset/e127961f57ec/

Log:    ffi.unpack(), extern "Python+C"

diff --git a/doc/source/ref.rst b/doc/source/ref.rst
--- a/doc/source/ref.rst
+++ b/doc/source/ref.rst
@@ -53,6 +53,9 @@
 value is casted between integers or pointers of any type.
 
 
+.. _ffi-errno:
+.. _ffi-getwinerror:
+
 ffi.errno, ffi.getwinerror()
 ++++++++++++++++++++++++++++
 
@@ -70,6 +73,9 @@
 function as usual.)
 
 
+.. _ffi-string:
+.. _ffi-unpack:
+
 ffi.string(), ffi.unpack()
 ++++++++++++++++++++++++++
 
@@ -78,8 +84,9 @@
 
 - If 'cdata' is a pointer or array of characters or bytes, returns the
   null-terminated string.  The returned string extends until the first
-  null character, or at most 'maxlen' characters.  If 'cdata' is an
-  array then 'maxlen' defaults to its length.  See ``ffi.buffer()`` below
+  null character.  The 'maxlen' argument limits how far we look for a
+  null character.  If 'cdata' is an
+  array then 'maxlen' defaults to its length.  See ``ffi.unpack()`` below
   for a way to continue past the first null character.  *Python 3:* this
   returns a ``bytes``, not a ``str``.
 
@@ -94,8 +101,26 @@
   If the value is out of range, it is simply returned as the stringified
   integer.
 
-**ffi.unpack(...)**: XXXXXXXXXXX
+**ffi.unpack(cdata, length)**: unpacks an array of C data of the given
+length, returning a Python string/unicode/list.  The 'cdata' should be
+a pointer; if it is an array it is first converted to the pointer
+type.  *New in version 1.6.*
 
+- If 'cdata' is a pointer to 'char', returns a byte string.  It does
+  not stop at the first null.  (An equivalent way to do that is
+  ``ffi.buffer(cdata, length)[:]``.)
+
+- If 'cdata' is a pointer to 'wchar_t', returns a unicode string.
+  ('length' is measured in number of wchar_t; it is not the size in
+  bytes.)
+
+- If 'cdata' is a pointer to anything else, returns a list, of the
+  given 'length'.  (A slower way to do that is ``[cdata[i] for i in
+  range(length)]``.)
+
+
+.. _ffi-buffer:
+.. _ffi-from-buffer:
 
 ffi.buffer(), ffi.from_buffer()
 +++++++++++++++++++++++++++++++
@@ -180,6 +205,10 @@
   the memory at ``myptr`` to the memory at ``myptr + 1``.
 
 
+.. _ffi-typeof:
+.. _ffi-sizeof:
+.. _ffi-alignof:
+
 ffi.typeof(), ffi.sizeof(), ffi.alignof()
 +++++++++++++++++++++++++++++++++++++++++
 
@@ -216,6 +245,7 @@
 the argument.  Corresponds to the ``__alignof__`` operator in GCC.
 
 
+.. _ffi-offsetof:
 .. _ffi-addressof:
 
 ffi.offsetof(), ffi.addressof()
@@ -260,6 +290,9 @@
 similarly, for a pointer, use ``ffi.new("foo_t *[1]")``.
 
 
+.. _ffi-cdata:
+.. _ffi-ctype:
+
 ffi.CData, ffi.CType
 ++++++++++++++++++++
 
@@ -297,6 +330,9 @@
 points in time, and using it in a ``with`` statement.
 
 
+.. _ffi-new-handle:
+.. _ffi-from-handle:
+
 ffi.new_handle(), ffi.from_handle()
 +++++++++++++++++++++++++++++++++++
 
@@ -341,6 +377,9 @@
 value compares equal.
 
 
+.. _ffi-dlopen:
+.. _ffi-dlclose:
+
 ffi.dlopen(), ffi.dlclose()
 +++++++++++++++++++++++++++
 
@@ -428,6 +467,9 @@
 .. __: https://bitbucket.org/cffi/cffi/issues/233/
 
 
+.. _ffi-getctype:
+.. _ffi-list-types:
+
 ffi.getctype(), ffi.list_types()
 ++++++++++++++++++++++++++++++++
 
diff --git a/doc/source/using.rst b/doc/source/using.rst
--- a/doc/source/using.rst
+++ b/doc/source/using.rst
@@ -577,12 +577,15 @@
 
 In case you want to access some ``extern "Python"`` function directly
 from the C code written in ``set_source()``, you need to write a
-forward static declaration.  The real implementation of this function
+forward declaration.  (By default it needs to be static, but see
+`next paragraph`__.)  The real implementation of this function
 is added by CFFI *after* the C code---this is needed because the
 declaration might use types defined by ``set_source()``
 (e.g. ``event_t`` above, from the ``#include``), so it cannot be
 generated before.
 
+.. __: `extern-python-c`_
+
 ::
 
     ffi.set_source("_demo_cffi", """
@@ -612,6 +615,46 @@
         }
     """)
 
+.. _extern-python-c:
+
+Extern "Python+C"
+~~~~~~~~~~~~~~~~~
+
+Functions declared with ``extern "Python"`` are generated as
+``static`` functions in the C source.  However, in some cases it is
+convenient to make them non-static, typically when you want to make
+them directly callable from other C source files.  To do that, you can
+say ``extern "Python+C"`` instead of just ``extern "Python"``.  *New
+in version 1.6.*
+
++------------------------------------+--------------------------------------+
+| if the cdef contains               | then CFFI generates                  |
++------------------------------------+--------------------------------------+
+| ``extern "Python" int f(int);``    | ``static int f(int) { /* code */ }`` |
++------------------------------------+--------------------------------------+
+| ``extern "Python+C" int f(int);``  | ``int f(int) { /* code */ }``        |
++------------------------------------+--------------------------------------+
+
+The name ``extern "Python+C"`` comes from the fact that we want an
+extern function in both senses: as an ``extern "Python"``, and as a
+C function that is not static.
+
+You cannot make CFFI generate additional macros or other
+compiler-specific stuff like the GCC ``__attribute__``.  You can only
+control whether the function should be ``static`` or not.  But often,
+these attributes must be written alongside the function *header*, and
+it is fine if the function *implementation* does not repeat them::
+
+    ffi.cdef("""
+        extern "Python+C" int f(int);      /* not static */
+    """)
+    ffi.set_source("_example_cffi", """
+        /* the forward declaration, setting a gcc attribute
+           (this line could also be in some .h file, to be included
+           both here and in the other C files of the project) */
+        int f(int) __attribute__((visibility("hidden")));
+    """)
+
 
 Extern "Python": reference
 ~~~~~~~~~~~~~~~~~~~~~~~~~~
diff --git a/doc/source/whatsnew.rst b/doc/source/whatsnew.rst
--- a/doc/source/whatsnew.rst
+++ b/doc/source/whatsnew.rst
@@ -6,11 +6,11 @@
 v1.6
 ====
 
-* ffi.list_types()
+* `ffi.list_types()`_
 
-* ffi.unpack()
+* `ffi.unpack()`_
 
-* extern "Python+C"
+* `extern "Python+C"`_
 
 * in API mode, ``lib.foo.__doc__`` contains the C signature now.  On
   CPython you can say ``help(lib.foo)``, but for some reason
@@ -18,8 +18,12 @@
   haven't yet figured out the hacks needed to convince ``pydoc`` to
   show more.  (You can use ``dir(lib)`` but it is not most helpful.)
 
-* Yet another attempt at robustness against CPython's interpreter
-  shutdown logic
+* Yet another attempt at robustness of ``ffi.def_extern()`` against
+  CPython's interpreter shutdown logic.
+
+.. _`ffi.list_types()`: ref.html#ffi-list-types
+.. _`ffi.unpack()`: ref.html#ffi-unpack
+.. _`extern "Python+C"`: using.html#extern-python-c
 
 
 v1.5.2
@@ -101,8 +105,8 @@
   the docs`__ of ``ffi.new_handle()`` has been here since v0.8!)
 
 .. __: using.html#extern-python
-.. __: ref.html#ffi-initonce
-.. __: using.html#ffi-new-handle
+.. __: ref.html#ffi-init-once
+.. __: ref.html#ffi-new-handle
 
 
 v1.3.1
@@ -212,7 +216,7 @@
   support for `alternative allocators`__.
 
 .. __: using.html#callbacks
-.. __: ref.html#new-allocator
+.. __: ref.html#ffi-new-allocator
 
 
 v1.1.2
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to