ctypes/cffi

这两个模块允许 Python 直接加载并调用动态链接库中的 C 函数,不需要编写 C 代码进行包装。其中 ctypes 是 Python 的内置库,而 cffi 是第三方库,性能更好且支持 PyPy.缺点是不支持 C++ 库(因为有 Name Mangling 和重载),只能 C 库。

使用方法是:

  • 先将 C 语言代码编译出 .dll/.so 动态库
  • 在 Python 里 import ctypes,然后用 lib = ctypes.CDLL('xxxx.so') 加载动态库
  • 对于每一个要调用的函数,定义其
    • 参数类型 lib.<function_name>.argtypes
    • 返回类型 lib.<function_name>.restype
  • lib.<function_name>(......) 调用函数

对于 lib.<function_name>(......) 中的函数参数,需要用 ctypes 中定义的 C 语言类型,如 c_int64 等等;遇到自定义数据类型的时候,还需要用 c_pointer 进行传递.

1
# toy example

PyBind11

PyBind11 是目前最流行、最推荐的 C++ 与 Python 交互工具。它是一个 Header-only 库,语法极其简洁,能够自动处理类型转换、引用计数和 STL 容器。

uv pip install pybind11 进行使用,然后在 CMakeLists.txt 添加依赖

1
2
3
4
5
cmake_minimum_required(VERSION 3.4)
project(example)

add_subdirectory(pybind11) # 指向 pybind11 源码
pybind11_add_module(example example.cpp)

example.cpp 里定义需要的函数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
// example.cpp
#include <pybind11/pybind11.h>

int add(int i, int j) {
return i + j;
}

namespace py = pybind11;

// 定义模块名
PYBIND11_MODULE(example, m) {
m.doc() = "pybind11 example plugin";
m.def("add", &add, "A function which adds two numbers");
}

最后在 Python 里进行调用

1
2
import example
print(example.add(10, 30))