cffi

cffi 是一个 Python 库,用于编写 C 语言扩展,同时提供了一个抽象层,以避免直接与 C API 交互。它允许 Python 代码通过一个简单的 Python 接口调用 C 代码,而不需要编写任何 C 代码。cffi 支持 Python 2 和 Python 3,并且可以与 Python C API 以及 Python 字节码 兼容。 以下是 cffi 的关键特点和用法:

关键特点

  1. 自动生成 C 代码cffi 可以从 Python 接口自动生成 C 代码,减少了手动编写 C 代码的需要。
  2. 与 C API 兼容:允许你使用 C API 来编写 Python 扩展,包括对 Python 对象的操作。
  3. 类型安全:提供类型检查,减少因类型错误导致的编程错误。
  4. 高效执行:生成的 C 代码可以高效执行,通常比纯 Python 实现快得多。
  5. 可移植性:支持多种平台和编译器,包括 Windows、macOS 和 Linux。

安装

可以通过pip安装cffi

pip install cffi

基本用法

以下是一些使用 cffi 的基本示例:

创建一个简单的 C 函数

首先,定义一个 Python 接口:

ffi = cffi.FFI()
ffi.cdef("""
    int add(int a, int b);
""")
# 编译 C 代码
lib = ffi.dlopen("./build/libadd.so")
# 调用 C 函数
result = lib.add(3, 4)
print(result)

然后,编译并链接 C 代码:

ffi.compile(verbose=True)

在这个例子中,我们定义了一个名为 add 的 C 函数,并使用 cffi.FFI() 创建了一个 FFI 对象。我们使用 ffi.dlopen 函数来加载生成的 C 库,并使用 lib.add 函数来调用 C 函数。

处理 Python 对象

ffi = cffi.FFI()
ffi.cdef("""
    void set_python_string(char *data, int len);
""")
# 编译 C 代码
ffi.compile(verbose=True)
# 创建 Python 对象
string = "Hello, World!"
# 将 Python 对象转换为 C 数据
c_string = ffi.new("char[]", string.encode('utf-8'))
# 调用 C 函数
lib.set_python_string(c_string, len(string))
# 从 C 数据转换回 Python 对象
python_string = ffi.string(c_string).decode('utf-8')
print(python_string)

在这个例子中,我们定义了一个名为 set_python_string 的 C 函数,它接受一个 C 字符串和它的长度。我们使用 ffi.new 函数创建了一个 C 字符串,并调用 C 函数来设置 Python 字符串。然后,我们使用 ffi.string 函数将 C 数据转换回 Python 字符串。

使用场景