在 Python 中无缝调用 C 语言函数的原生模块
ctypes 是 Python 标准库中的一个模块,允许你直接调用共享库(如 Windows 的 .dll 或 Linux/macOS 的 .so)中的 C 函数。
它无需编写额外的绑定代码,是 Python 与 C 交互最轻量级的方式之一。
适用于以下场景:
下面是一个在 Linux/macOS 上调用标准 C 库 libc 中 printf 函数的例子:
import ctypes
# 加载 C 标准库
libc = ctypes.CDLL("libc.so.6") # Linux
# libc = ctypes.CDLL("libc.dylib") # macOS
# 调用 printf
libc.printf(b"Hello from C!\\n")
在 Windows 上调用 msvcrt.dll:
import ctypes
msvcrt = ctypes.CDLL("msvcrt.dll")
msvcrt.printf(b"Hello from Windows C!\\n")
ctypes 提供了与 C 类型对应的 Python 类型,例如:
ctypes.c_int → intctypes.c_char_p → bytes(字符串需编码为 bytes)ctypes.c_double → floatctypes.POINTER(c_int) → 指针指定函数参数和返回值类型可提高安全性和正确性:
import ctypes
libc = ctypes.CDLL("libc.so.6")
libc.strlen.argtypes = [ctypes.c_char_p]
libc.strlen.restype = ctypes.c_size_t
length = libc.strlen(b"Hello ctypes!")
print(length) # 输出: 13
ctypes 还支持定义 C 风格的结构体和传递 Python 函数作为回调:
import ctypes
class Point(ctypes.Structure):
_fields_ = [("x", ctypes.c_int),
("y", ctypes.c_int)]
def callback(x):
print(f"Callback called with: {x}")
return x * 2
# 假设有一个 C 函数接受函数指针
# typedef int (*callback_t)(int);
# int process(callback_t cb, int value);
# 使用 ctypes.CFUNCTYPE 定义回调类型
CALLBACK_TYPE = ctypes.CFUNCTYPE(ctypes.c_int, ctypes.c_int)
cb_func = CALLBACK_TYPE(callback)
# 调用 C 函数(伪代码)
# result = some_c_lib.process(cb_func, 10)
bytes 而非 str(C 字符串)argtypes 和 restype 避免类型错误.dll vs .so vs .dylib)cffi 或 pybind11 替代