Interfacing with C/C++ Libraries

https://d33wubrfki0l68.cloudfront.net/301a807550ffc9faf2c2e9db567469c8f97affc7/8c90c/_images/34725951345_c8f5959a2e_k_d.jpg

C Foreign Function Interface

CFFI provides a simple to usemechanism for interfacing with C from both CPython and PyPy. It supports twomodes: an inline ABI compatibility mode (example provided below), which allowsyou to dynamically load and run functions from executable modules (essentiallyexposing the same functionality as LoadLibrary or dlopen), and an API mode,which allows you to build C extension modules.

ABI Interaction




  1. 1
    2
    3
    4
    5
    6
    7





  1. from cffi import FFI
    ffi = FFI()
    ffi.cdef("size_t strlen(const char*);")
    clib = ffi.dlopen(None)
    length = clib.strlen("String to be evaluated.")
    # prints: 23
    print("{}".format(length))


ctypes

ctypes is the de facto standardlibrary for interfacing with C/C++ from CPython, and it provides not onlyfull access to the native C interface of most major operating systems (e.g.,kernel32 on Windows, or libc on *nix), but also provides support for loadingand interfacing with dynamic libraries, such as DLLs or shared objects, atruntime. It brings along with it a whole host of types for interactingwith system APIs, and allows you to rather easily define your own complextypes, such as structs and unions, and allows you to modify things such aspadding and alignment, if needed. It can be a bit crufty to use, but inconjunction with the structmodule, you are essentially provided full control over how your data types gettranslated into something usable by a pure C/C++ method.

Struct Equivalents

MyStruct.h




  1. 1
    2
    3
    4





  1. struct my_struct {
    int a;
    int b;
    };


MyStruct.py




  1. 1
    2
    3
    4





  1. import ctypes
    class mystruct(ctypes.Structure):
    _fields
    = [("a", c_int),
    ("b", c_int)]


SWIG

SWIG, though not strictly Python focused (it supports alarge number of scripting languages), is a tool for generating bindings forinterpreted languages from C/C++ header files. It is extremely simple to use:the consumer simply needs to define an interface file (detailed in thetutorial and documentations), include the requisite C/C++ headers, and runthe build tool against them. While it does have some limits (it currentlyseems to have issues with a small subset of newer C++ features, and gettingtemplate-heavy code to work can be a bit verbose), it provides a great dealof power and exposes lots of features to Python with little effort.Additionally, you can easily extend the bindings SWIG creates (in theinterface file) to overload operators and built-in methods, effectively re-cast C++ exceptions to be catchable by Python, etc.

Example: Overloading repr

MyClass.h




  1. 1
    2
    3
    4
    5
    6
    7





  1. #include <string>
    class MyClass {
    private:
    std::string name;
    public:
    std::string getName();
    };


myclass.i




  1. 1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16





  1. %include "string.i"

    %module myclass
    %{
    #include <string>
    #include "MyClass.h"
    %}

    %extend MyClass {
    std::string repr()
    {
    return $self->getName();
    }
    }

    %include "MyClass.h"


Boost.Python

Boost.Pythonrequires a bit more manual work to expose C++ object functionality, butit is capable of providing all the same features SWIG does and then some,to include providing wrappers to access PyObjects in C++, extracting SWIGwrapper objects, and even embedding bits of Python into your C++ code.

原文: https://docs.python-guide.org/scenarios/clibs/