轻松调用 C 语言函数,无需编写 C 扩展
ctypes 是 Python 标准库中的一个模块,用于在 Python 中加载和调用动态链接库(如 Windows 的 .dll 或 Linux/macOS 的 .so/.dylib),并能与 C 兼容的数据类型进行交互。
它无需编译,纯 Python 实现,非常适合快速集成已有的 C 库。
以下代码展示了如何调用系统标准 C 库中的 printf 函数(Linux/macOS):
import ctypes
# 加载 C 标准库(Linux/macOS)
libc = ctypes.CDLL("libc.so.6") # macOS 可能是 libSystem.dylib
# 调用 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.abs.argtypes = [ctypes.c_int]
libc.abs.restype = ctypes.c_int
result = libc.abs(-42)
print(result) # 输出: 42
可以使用 ctypes.Structure 定义与 C 对应的结构体:
import ctypes
class Point(ctypes.Structure):
_fields_ = [("x", ctypes.c_int),
("y", ctypes.c_int)]
p = Point(10, 20)
print(f"Point: ({p.x}, {p.y})")
.encode() 转换。ctypes.CFUNCTYPE 定义 Python 回调供 C 调用。.dll,Linux 用 .so,macOS 用 .dylib。假设你有一个 C 文件 math_utils.c:
// math_utils.c
int add(int a, int b) {
return a + b;
}
编译为共享库:
# Linux
gcc -shared -fPIC -o libmath.so math_utils.c
# Windows (MinGW)
gcc -shared -o math.dll math_utils.c
Python 调用:
import ctypes
lib = ctypes.CDLL("./libmath.so") # 或 ./math.dll
lib.add.argtypes = [ctypes.c_int, ctypes.c_int]
lib.add.restype = ctypes.c_int
print(lib.add(3, 5)) # 输出: 8