python作为一种胶水语言具有较高的开发效率, 但是其运行效率比较低, 当计算量比较大时,显得力不从心. 而ctypes是python下的一个可以链接c/c++的一个库. 可以将C函数编译成动态链接库, 即window下的.dll文件或者是linux下的.so文件. 这样我们通过使用cytpes可以加速代码的运行速度.
例如,用printf函数打印
import platform
from ctypes import *
if platform.system() == 'Windows':
libc = cdll.LoadLibrary('msvcrt.dll')
elif platform.system() =='Linux':
libc = cdll.LoadLibrary('libc.so.6')
libc.printf('Hello world!\n')
1.数据类型, ctypes作为联系python和c的接口, 其对应的数据类型如下:
注:Python 中的类型,除了 None,int, long, Byte String,Unicode String 作为 C 函数的参数默认提供转换外,其它类型都必须显式提供转换。
None:对应 C 中的 NULL
int, long: 对应 C 中的 int,具体实现时会根据机器字长自动适配。
特别需要注意的是,在python3中:
Byte String:对应 C 中的一个字符串指针 char * ,指向一块内存区域。(字符串前面会加小b, b"helloworld")
Unicode String :对应 C 中一个宽字符串指针 wchar_t *,指向一块内存区域。(对应的就是字符串, "helloworld")
在python2中恰好相反.
2指定函数的参数类型和返回类型
例如,我们用c++写一个距离公式,然后用python调用.
命名c++文件为dist.cpp:
#include
#include
using namespace std;
extern "C" float Dist(float ax,float ay,float az,float bx,float by,float bz){
return(sqrt((ax-bx)*(ax-bx)+(ay-by)*(ay-by)+(az-bz)*(az-bz)));}
写好以后编译成.so文件:g++ -o dist.so -shared -fPIC dist.cpp
接着,在python3下用ctypes调用dist.so:
test = cdll.LoadLibrary("./dist.so")
test.dist.argtypes = [c_float, c_float, c_float, c_float, c_float, c_float]
test.dist.restype = c_float
a =[3,0,0]
a1 = [0,4,0]
r = test.Dist(c_float(a[0]),c_float(a[1]),c_float(a[2]), c_float(a1[0]),c_float(a1[1]),c_float(a1[2]))
其中test.dist.argtypes = [c_float, c_float, c_float, c_float, c_float, c_float]表示函数的6个参数均为float型,
test.dist.restype = c_float函数的返回类型为float型.
3.结构体和联合体(Structures and unions)
>>> from ctypes import *
>>> class POINT(Structure):
... _fields_ = [("x", c_int),
... ("y", c_int)]
...
>>> point = POINT(10, 20)
>>> print point.x, point.y
10 20
>>> point = POINT(y=5)
>>> print point.x, point.y
0 5
>>> POINT(1, 2, 3)
Traceback (most recent call last):
File "", line 1, in
ValueError: too many initializers
>>>
后续再更新联合体以及指针等