[pypy-commit] cffi default: Documentation updates

arigo noreply at buildbot.pypy.org
Fri Jun 29 16:52:13 CEST 2012


Author: Armin Rigo <arigo at tunes.org>
Branch: 
Changeset: r570:71f5e672a341
Date: 2012-06-29 16:52 +0200
http://bitbucket.org/cffi/cffi/changeset/71f5e672a341/

Log:	Documentation updates

diff --git a/doc/source/index.rst b/doc/source/index.rst
--- a/doc/source/index.rst
+++ b/doc/source/index.rst
@@ -242,7 +242,7 @@
   size_t, ssize_t
 
 As we will see on `the verification step`_ below, the declarations can
-also contain "``...``" at various places; there are placeholders that will
+also contain "``...``" at various places; these are placeholders that will
 be completed by a call to ``verify()``.
 
 
@@ -250,11 +250,14 @@
 -----------------
 
 ``ffi.dlopen(libpath)``: this function opens a shared library and
-returns a module-like library object.  You can use the library object to
-call the functions previously declared by ``ffi.cdef()``, and to read or
-write global variables.  Note that you can use a single ``cdef()`` to
-declare functions from multiple libraries, as long as you load each of
-them with ``dlopen()`` and access the functions from the correct one.
+returns a module-like library object.  You need to use *either*
+``ffi.dlopen()`` *or* ``ffi.verify()``, documented below_.
+
+You can use the library object to call the functions previously declared
+by ``ffi.cdef()``, and to read or write global variables.  Note that you
+can use a single ``cdef()`` to declare functions from multiple
+libraries, as long as you load each of them with ``dlopen()`` and access
+the functions from the correct one.
 
 The ``libpath`` is the file name of the shared library, which can
 contain a full path or not (in which case it is searched in standard
@@ -274,6 +277,8 @@
 cannot call functions from a library without linking it in your program,
 as ``dlopen()`` does dynamically in C.
 
+.. _below:
+
 
 The verification step
 ---------------------
@@ -281,12 +286,15 @@
 ``ffi.verify(source, **kwargs)``: verifies that the current ffi signatures
 compile on this machine, and return a dynamic library object.  The
 dynamic library can be used to call functions and access global
-variables declared by a previous ``ffi.cdef()``.  The library is compiled
-by the C compiler: it gives you C-level API compatibility (including
-calling macros, as long as you declared them as functions in
-``ffi.cdef()``).  This differs from ``ffi.dlopen()``, which requires
-ABI-level compatibility and must be called several times to open several
-shared libraries.
+variables declared by a previous ``ffi.cdef()``.  You don't need to use
+``ffi.dlopen()`` in this case.
+
+The returned library is a custom one, compiled just-in-time by the C
+compiler: it gives you C-level API compatibility (including calling
+macros, as long as you declared them as functions in ``ffi.cdef()``).
+This differs from ``ffi.dlopen()``, which requires ABI-level
+compatibility and must be called several times to open several shared
+libraries.
 
 On top of CPython, the new library is actually a CPython C extension
 module.  This solution constrains you to have a C compiler (future work
@@ -322,16 +330,19 @@
    if you pass a ``int *`` argument to a function expecting a ``long *``.
 
 Moreover, you can use "``...``" in the following places in the ``cdef()``
-for leaving details unspecified (filled in by the C compiler):
+for leaving details unspecified, which are then completed by the C
+compiler during ``verify()``:
 
 *  structure declarations: any ``struct`` that ends with "``...;``" is
-   partial.  It will be completed by the compiler.  (But note that you
-   can only access fields that you declared.)  Any ``struct``
-   declaration without "``...;``" is assumed to be exact, and this is
+   partial: it may be missing fields and/or have them declared out of order.
+   This declaration will be corrected by the compiler.  (But note that you
+   can only access fields that you declared, not others.)  Any ``struct``
+   declaration which doesn't use "``...``" is assumed to be exact, but this is
    checked: you get a ``VerificationError`` if it is not.
 
 *  unknown types: the syntax "``typedef ... foo_t;``" declares the type
-   ``foo_t`` as opaque.
+   ``foo_t`` as opaque.  Useful mainly for when the API takes and returns
+   ``foo_t *`` without you needing to looking inside the ``foo_t``.
 
 *  array lengths: when used as structure fields, arrays can have an
    unspecified length, as in "``int n[];``".  The length is completed
@@ -356,6 +367,14 @@
    to write the ``const`` together with the variable name, as in
    ``static char *const FOO;``).
 
+Currently, finding automatically the size of an integer type is not
+supported.  You need to declare them with ``typedef int myint;`` or
+``typedef long myint;`` or ``typedef long long myint;`` or their
+unsigned equivalent.  Depending on the usage, the C compiler might give
+warnings if you misdeclare ``myint`` as the wrong type even if it is
+equivalent on this platform (e.g. using ``long`` instead of ``long
+long`` or vice-versa on 64-bit Linux).
+
 
 Working with pointers, structures and arrays
 --------------------------------------------
@@ -393,14 +412,6 @@
 ownership, so you must keep it alive.  As soon as you forget it, then
 the casted pointer will point to garbage.)
 
-.. versionchanged:: 0.2
-   Allocating a new struct also returns an owning pointer object.
-   But --- as an exception to the above rule --- dereferencing this
-   particular pointer object also returns an *owning* struct object.
-   This is done for cases where you really want to have a struct
-   object but don't have any convenient place to keep the original
-   pointer object alive.
-
 The cdata objects support mostly the same operations as in C: you can
 read or write from pointers, arrays and structures.  Dereferencing a
 pointer is done usually in C with the syntax ``*p``, which is not valid
@@ -419,10 +430,19 @@
 fit nicely in the model, and it does not seem to be needed here).
 
 Any operation that would in C return a pointer or array or struct type
-gives you a new cdata object.  Unlike the "original" one, these new
+gives you a fresh cdata object.  Unlike the "original" one, these fresh
 cdata objects don't have ownership: they are merely references to
 existing memory.
 
+.. versionchanged:: 0.2
+   As an exception the above rule, dereferencing a pointer that owns a
+   *struct* or *union* object returns a cdata struct or union object
+   that "co-owns" the same memory.  Thus in this case there are two
+   objects that can keep the memory alive.  This is done for cases where
+   you really want to have a struct object but don't have any convenient
+   place to keep alive the original pointer object (returned by
+   ``ffi.new()``).
+
 Example::
 
     ffi.cdef("void somefunction(int *);")
@@ -487,8 +507,8 @@
     array = ffi.new("int[1000]")      # CFFI 1st equivalent
     array = ffi.new("int[]", 1000)    # CFFI 2nd equivalent
 
-This is useful if the length is not actually a constant, to avoid doing
-things like ``ffi.new("int[%d]"%x)``.  Indeed, this is not recommended:
+This is useful if the length is not actually a constant, to avoid things
+like ``ffi.new("int[%d]" % x)``.  Indeed, this is not recommended:
 ``ffi`` normally caches the string ``"int[]"`` to not need to re-parse
 it all the time.
 
@@ -501,11 +521,12 @@
 same rules as reading a structure field.  For example::
 
     ffi.cdef("""
-        int foo(int a, int b);
+        int foo(short a, int b);
     """)
     lib = ffi.verify("#include <foo.h>")
 
     n = lib.foo(2, 3)     # returns a normal integer
+    lib.foo(40000, 3)     # raises OverflowError
 
 As an extension, you can pass to ``char *`` arguments a normal Python
 string (but don't pass a normal Python string to functions that take a
@@ -529,7 +550,7 @@
     >>> lib.function_returning_a_struct()
     <cdata 'struct foo_s' owning 8 bytes>
 
-There are a few "obscure-case" limitations to the argument types and
+There are a few (obscure) limitations to the argument types and
 return type.  You cannot pass directly as argument a union, nor a struct
 which uses bitfields (note that passing a *pointer* to anything is
 fine).  If you pass a struct, the struct type cannot have been declared
@@ -537,7 +558,8 @@
 completely in ``cdef()``.
 
 .. versionadded:: 0.2
-   Aside from these limitations, functions and callbacks can return structs.
+   Aside from these limitations, functions and callbacks can now return
+   structs.
 
 
 Variadic function calls
@@ -558,6 +580,7 @@
     C.printf("hello, %d\n", ffi.cast("int", 42))
     C.printf("hello, %ld\n", ffi.cast("long", 42))
     C.printf("hello, %f\n", ffi.cast("double", 42))
+    C.printf("hello, %s\n", ffi.new("char[]", "world"))
 
 
 Callbacks
@@ -647,7 +670,7 @@
 representation of the given C type.  If non-empty, the "extra" string is
 appended (or inserted at the right place in more complicated cases); it
 can be the name of a variable to declare, or an extra part of the type
-like ``"*"`` or ``"[5]"``, so that for example
+like ``"*"`` or ``"[5]"``.  For example
 ``ffi.getcname(ffi.typeof(x), "*")`` returns the string representation
 of the C type "pointer to the same type than x".
 


More information about the pypy-commit mailing list