[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