summaryrefslogtreecommitdiff
path: root/doc/source/ref.rst
diff options
context:
space:
mode:
authorArmin Rigo <arigo@tunes.org>2016-06-06 14:53:57 +0200
committerArmin Rigo <arigo@tunes.org>2016-06-06 14:53:57 +0200
commitb94f3f80e0c795ea0192199432c2cb3464a24bf7 (patch)
tree830187e720767f72b15946903ca332537b798ab4 /doc/source/ref.rst
parent4c47ab57cc1e1b872a9076ef4ab22364ef32896f (diff)
downloadcffi-b94f3f80e0c795ea0192199432c2cb3464a24bf7.tar.gz
Write down a typical ffi.new_handle() usage example
Diffstat (limited to 'doc/source/ref.rst')
-rw-r--r--doc/source/ref.rst29
1 files changed, 29 insertions, 0 deletions
diff --git a/doc/source/ref.rst b/doc/source/ref.rst
index dca2150..3eab944 100644
--- a/doc/source/ref.rst
+++ b/doc/source/ref.rst
@@ -359,6 +359,8 @@ you can use **ffi.from_handle(p)** to retrieve the original
*Calling ffi.from_handle(p) is invalid and will likely crash if
the cdata object returned by new_handle() is not kept alive!*
+See a `typical usage example`_ below.
+
(In case you are wondering, this ``void *`` is not the ``PyObject *``
pointer. This wouldn't make sense on PyPy anyway.)
@@ -391,6 +393,33 @@ to a global set. It can later be removed from the set by
``global_set.discard(p)``, with ``p`` any cdata object whose ``void *``
value compares equal.
+.. _`typical usage example`:
+
+Usage example: suppose you have a C library where you must call a
+``lib.process_document()`` function which invokes some callback. The
+``process_document()`` function receives a pointer to a callback and a
+``void *`` argument. The callback is then invoked with the ``void
+*data`` argument that is equal to the provided value. In this typical
+case, you can implement it like this (out-of-line API mode)::
+
+ class MyDocument:
+ ...
+
+ def process(self):
+ lib.process_document(lib.my_callback, # the callback
+ ffi.new_handle(self), # 'void *data'
+ args...)
+ # 'self' stay alive at least until here, which means that
+ # the ffi.from_handle() done in my_callback() are safe
+
+ def callback(self, arg1, arg2):
+ ...
+
+ # the actual callback is this one-liner global function:
+ @ffi.def_extern
+ def my_callback(arg1, arg2, data):
+ return ffi.from_handle(data).callback(arg1, arg2)
+
.. _ffi-dlopen:
.. _ffi-dlclose: