ctypes 的全称是 C types foreign function library for
Python。它的主要作用是在 Python 中加载并调用 C
语言动态链接库(Shared
Library),并在两种语言之间传递数据, 实现 Python
与底层高性能代码的无缝结合。
基本用法结构
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| import ctypes
lib = ctypes.CDLL("./mylib.so")
lib.add.argtypes = [ctypes.c_double, ctypes.c_double] lib.add.restype = ctypes.c_double
result = lib.add(1.5, 2.3) print(result)
|
主要功能分类
加载动态库 ctypes
提供了多种函数来加载不同类型的动态库,常用的有:
函数 说明 ctypes.CDLL(path) 加载普通 C 动态库(标准调用约定)
ctypes.WinDLL(path) Windows 专用,适用于 stdcall 调用约定
ctypes.PyDLL(path) Python 扩展库加载(保留 GIL)
常见的 C 类型映射 C 类型 Python 映射 int
ctypes.c_int float ctypes.c_float double ctypes.c_double char
ctypes.c_char char* ctypes.c_char_p void* ctypes.c_void_p bool
ctypes.c_bool struct 自定义 ctypes.Structure 子类
传递数组 C 语言中常常需要传递数组指针, 可以用 ctypes
的 POINTER 或 Array 来完成。
POINTER的作用是创建一个指向某种类型的指针类型。
1 2 3 4 5 6 7 8 9 10 11
| import ctypes
DoubleArray = ctypes.c_double * 5 arr = DoubleArray(1.0, 2.0, 3.0, 4.0, 5.0)
lib.mean.argtypes = [ctypes.POINTER(ctypes.c_double), ctypes.c_int] lib.mean.restype = ctypes.c_double
print(lib.mean(arr, 5))
|
除此之外, 还可以直接用 NumPy 数组的 .ctypes 接口拿到指针:
1 2 3 4 5
| import numpy as np
arr = np.arange(10, dtype=np.double) ptr = arr.ctypes.data_as(ctypes.POINTER(ctypes.c_double)) lib.mean(ptr, len(arr))
|
示例
下面是一个完整的示例,展示了如何用 ctypes 调用一个简单的 C
动态库函数。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63
|
import ctypes import numpy as np
lib = ctypes.CDLL('./fast_indicators.so')
lib.calculate_sma.argtypes = [ ctypes.POINTER(ctypes.c_double), ctypes.c_int, ctypes.c_int, ctypes.POINTER(ctypes.c_double) ]
def fast_sma(prices, period): """使用C++实现的快速移动平均""" prices_arr = (ctypes.c_double * len(prices))(*prices) result_arr = (ctypes.c_double * len(prices))()
lib.calculate_sma(prices_arr, len(prices), period, result_arr)
return np.array(result_arr)
class HybridStrategy: def __init__(self): self.prices = []
def on_tick(self, price): self.prices.append(price)
if len(self.prices) > 100: sma_values = fast_sma(self.prices[-100:], 20) sma = sma_values[-1]
if price > sma: return "BUY" elif price < sma: return "SELL" return "HOLD"
if __name__ == "__main__": strategy = HybridStrategy() for price in np.random.rand(200) * 100: action = strategy.on_tick(price) if action != "HOLD": print(f"Price: {price:.2f}, Action: {action}")
|