Skip to content

Commit 184ef03

Browse files
committed
Merge pull request realpython#636 from ambray/aaron/add-clib-doc
Aaron/add clib doc
2 parents de12022 + 3f05084 commit 184ef03

File tree

2 files changed

+130
-0
lines changed

2 files changed

+130
-0
lines changed

docs/contents.rst.inc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@ different scenarios.
6363
scenarios/xml
6464
scenarios/json
6565
scenarios/crypto
66+
scenarios/clibs
6667

6768

6869
Shipping Great Code

docs/scenarios/clibs.rst

Lines changed: 129 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,129 @@
1+
Interfacing with C/C++ Libraries
2+
================================
3+
4+
C Foreign Function Interface
5+
----------------------------
6+
7+
`CFFI <https://cffi.readthedocs.org/en/latest/>`_ provides a simple to use
8+
mechanism for interfacing with C from both CPython and PyPy. It supports two
9+
modes: an inline ABI compatibility mode (example provided below), which allows
10+
you to dynamically load and run functions from executable modules (essentially
11+
exposing the same functionality as LoadLibrary or dlopen), and an API mode,
12+
which allows you to build C extension modules.
13+
14+
ABI Interaction
15+
~~~~~~~~~~~~~~~
16+
17+
.. code-block:: python
18+
:linenos:
19+
20+
from cffi import FFI
21+
ffi = FFI()
22+
ffi.cdef("size_t strlen(const char*);")
23+
clib = ffi.dlopen(None)
24+
length = clib.strlen("String to be evaluated.")
25+
# prints: 23
26+
print("{}".format(length))
27+
28+
ctypes
29+
------
30+
31+
`ctypes <https://docs.python.org/3/library/ctypes.html>`_ is the de facto
32+
library for interfacing with C/C++ from CPython, and it provides not only
33+
full access to the native C interface of most major operating systems (e.g.,
34+
kernel32 on Windows, or libc on \*nix), but also provides support for loading
35+
and interfacing with dynamic libraries, such as DLLs or shared objects at
36+
runtime. It does bring along with it a whole host of types for interacting
37+
with system APIs, and allows you to rather easily define your own complex
38+
types, such as structs and unions, and allows you to modify things such as
39+
padding and alignment, if needed. It can be a bit crufty to use, but in
40+
conjunction with the `struct <https://docs.python.org/3.5/library/struct.html>`_
41+
module, you are essentially provided full control over how your data types get
42+
translated into something something usable by a pure C(++) method.
43+
44+
Struct Equivalents
45+
~~~~~~~~~~~~~~~~~~
46+
47+
:file:`MyStruct.h`
48+
49+
.. code-block:: c
50+
:linenos:
51+
52+
struct my_struct {
53+
int a;
54+
int b;
55+
};
56+
57+
:file:`MyStruct.py`
58+
59+
.. code-block:: python
60+
:linenos:
61+
62+
import ctypes
63+
class my_struct(ctypes.Structure):
64+
_fields_ = [("a", c_int),
65+
("b", c_int)]
66+
67+
SWIG
68+
----
69+
70+
`SWIG <http://www.swig.org>`_, though not strictly Python focused (it supports a
71+
large number of scripting languages), is a tool for generating bindings for
72+
interpreted languages from C/C++ header files. It is extremely simple to use:
73+
the consumer simply needs to define an interface file (detailed in the
74+
tutorial and documentations), include the requisite C/C++ headers, and run
75+
the build tool against them. While it does have some limits, (it currently
76+
seems to have issues with a small subset of newer C++ features, and getting
77+
template-heavy code to work can be a bit verbose), it provides a great deal
78+
of power and exposes lots of features to Python with little effort.
79+
Additionally, you can easily extend the bindings SWIG creates (in the
80+
interface file) to overload operators and built-in methods, effectively re-
81+
cast C++ exceptions to be catchable by Python, etc.
82+
83+
Example: Overloading __repr__
84+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
85+
86+
:file:`MyClass.h`
87+
88+
.. code-block:: c++
89+
:linenos:
90+
91+
#include <string>
92+
class MyClass {
93+
private:
94+
std::string name;
95+
public:
96+
std::string getName();
97+
};
98+
99+
:file:`myclass.i`
100+
101+
.. code-block:: c++
102+
:linenos:
103+
104+
%include "string.i"
105+
106+
%module myclass
107+
%{
108+
#include <string>
109+
#include "MyClass.h"
110+
%}
111+
112+
%extend MyClass {
113+
std::string __repr__()
114+
{
115+
return $self->getName();
116+
}
117+
}
118+
119+
%include "MyClass.h"
120+
121+
122+
Boost.Python
123+
------------
124+
125+
`Boost.Python <http://www.boost.org/doc/libs/1_59_0/libs/python/doc/>`_
126+
requires a bit more manual work to expose C++ object functionality, but
127+
it is capable of providing all the same features SWIG does and then some,
128+
to include providing wrappers to access PyObjects in C++, extracting SWIG-
129+
wrapper objects, and even embedding bits of Python into your C++ code.

0 commit comments

Comments
 (0)