Python调用C/C++动态链接库----来源于cookbook第十五章
记录第十五章中比较有意思的部分
使用ctypes来从python中调用C/C++的动态链接库
将C/C++代码编译成动态链接库,然后使用Python的ctypes模块加以调用,从而提升整体执行效率。
其中C/C++函数原型主要有以下几种主要的形式,分别对应不同的调用方法:
- 仅常规类型,无指针
- 包含指针的常规类型,或使用指针实现多返回值
- C数组
- 结构体
假设有以下的C函数原型
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
|
int funa(int x, double y);
int funb(int x, double *y);
double func(double *a ,int n);
struct Point { double x,y; } double fund(Point *x, Point *y);
|
且上述的函数被编译成动态链接库func.dll
,那么在Python中需要按照以下方法来调用对应函数
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
| import ctypes
dll = ctypes.cdll.LoadLibrary("func.dll")
def funa_warp(x, y): funa = dll.funa funa.argtypes = (ctypes.c_int, ctypes.c_double) funa.restype = ctypes.c_int return funa(x, y)
def funb_warp(x, y): funb = dll.funb funb.argtypes = (ctypes.c_int, ctypes.POINTER(ctypes.c_double)) funb.restype = ctypes.c_int rem = ctypes.c_double() res = funb(x, rem) return res, rem.value
def func_warp(list_): func = dll.func val = ((ctypes.c_double) * len(list_))(*list_) func.argtypes = (val, ctypes.c_int) func.restype = ctypes.c_double return func(val, len(list_))
class Point(ctypes.Structure): _fields_ = [('x', ctypes.c_double), ('y', ctypes.c_double)]
def fund_warp(p1, p2): fund = dll.fund fund.argtypes = (ctypes.POINTER(Point), ctypes.POINTER(Point)) fund.restype = ctypes.c_double
return fund(p1, p2)
|
除此之外,还有比如指针数组、结构体指针数组等等比较复杂的东西,当时使用的相对比较少。