C/C++类库接口

../_images/34725951345_c8f5959a2e_k_d.jpg

C外部功能接口

CFFI 提供了一种简单易用的机制,用于从cpython和pypy与C进行接口。它支持两种模式:内联 ABI 兼容性模式(下面提供的示例),允许您从可执行模块动态加载和运行函数(基本上公开与 LoadLibrarydlopen )和API模式,允许您构建C扩展模块。

ABI相互作用

1
2
3
4
5
6
7
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))

C型

ctypes 是与cPython接口的C/C++接口的事实标准库,它不仅提供了对大多数主要操作系统的本地C接口的完全访问(例如Windows上的Keln32,或LIBC)。 * 但也支持在运行时加载和与动态库(如DLL或共享对象)接口。它为与系统API交互带来了一整套类型,允许您相当容易地定义自己的复杂类型,如结构和联合,并允许您根据需要修改填充和对齐等内容。使用起来可能有点粗糙,但与 struct 模块,基本上可以完全控制您的数据类型是如何通过纯C/C++方法转换成可用的。

结构等效物

MyStruct.h

1
2
3
4
struct my_struct {
    int a;
    int b;
};

MyStruct.py

1
2
3
4
import ctypes
class my_struct(ctypes.Structure):
    _fields_ = [("a", c_int),
                ("b", c_int)]

SWIG

SWIG <http://www.swig.org> 虽然不是严格的Python焦点(它支持大量脚本语言),但它是从C/C++头文件生成解释语言绑定的工具。使用起来非常简单:消费者只需要定义一个接口文件(在教程和文档中详细说明),包括必要的C/C++头文件,并运行构建工具来对付它们。虽然它确实有一些限制(它现在似乎有一个新的C++特性的小子集的问题,并使模板重代码工作,可以有点冗长),它提供了大量的权力,并暴露了很多的特点,Python用很少的努力。此外,您还可以轻松地将SWIG创建的绑定(在接口文件中)扩展为过载运算符和内置方法,有效地重铸C++异常以被Python捕获。

示例:重载 __repr__

MyClass.h

1
2
3
4
5
6
7
#include <string>
class MyClass {
private:
    std::string name;
public:
    std::string getName();
};

myclass.i

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
%include "string.i"

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

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

%include "MyClass.h"

Boost.Python

Boost.Python 需要更多的手工工作来公开C++对象功能,但它能够提供SWIG所做的所有相同的功能,还有一些功能,包括在C++中提供包装来访问pyObject,提取SWIG包装对象,甚至将Python的比特嵌入到C++代码中。