利用python的ctypes模块可以在python中调用c/c++写的代码。
但是c/c++写的代码要编译成dll文件,在dll中导出你想在python中调用的函数或变量。
ctypes的详细用法见官方文档: http://docs.python.org/2/library/ctypes.html
这里只是个人的一个简单总结。
1. 加载Windows系统自带的dll文件:
#加载cdecl调用约定的dll
msvcrt =cdll.msvcrt
#加载stdcall调用约定的dll
kernel32 =windll.kernel32
2. 加载自己dll文件,假如为addFuncDll,方式如下:
mydll =CDLL("addFuncDll.dll")
或者 mydll = cdll.addFuncDll
如果其中有函数add,计算两个整数的和,则使用方式如下:
result=mydll.add(4,5)
可以多一步指明add函数的参数类型(也可不指明):
mydll.add.argtypes= [c_int,c_int]
3. 结构体在python中定义为Structure的子类如下:
class POINT(Structure):
_fields_ = [("x", c_int),
("y",c_int)]
_fields中每一项为元组(成员名称,类型)
结构体还可以用于其他的结构体:
class RECT(Structure):
_fields_ = [("upperleft",POINT),
("lowerright",POINT)]
4. 数组定义
一维数组:
ARRAY = (c_int *4) #包含4个整数的数组类型
a = ARRAY() #声明包含4个整数的数组,初值均为0
二维数组:
ARRAY2D = (c_int *4)*5 #4×5的数组类型
a = ARRAY2D() #声明4*5的数组,初值均为0,要两个for循环遍历
5. 指针
函数byref()和pointer()可以获取变量对应的指针
使用byref()更快,而pointer()会构造一个新的指针对象
6. 字符串
#第一种方式:c_char_p
s = "Hello,World"
c_s = c_char_p(s) #改变c_s.value不会改变原字符串s
# 第二种方式:create_string_buffer,字符串以空字符结尾
p =create_string_buffer("Hello")
print sizeof(p),repr(p.raw) #输出 6 'Hello\x00'
p =create_string_buffer("Hello", 10)
print sizeof(p),repr(p.raw),p.value #输出 10 'Hello\x00\x00\x00\x00\x00' Hello
7. 有时碰到返回值或参数为函数指针,在ctypes中声明该种类型有两种方式:WINFUNCTYPE和CFUNCTYPE
Windows函数可以这样:
prototype =WINFUNCTYPE(c_int, HWND, LPCSTR, LPCSTR, UINT)
即返回值类型为c_int,其他参数类型依次为HWND, LPCSTR, LPCSTR, UINT
调用MessageBox函数如下:
自己定义的函数可以这样,以上面提到的add函数为例:
ADDFUNC = CFUNCTYPE(c_int, c_int, c_int)
即返回值类型为c_int,其他参数类型依次为c_int,c_int
8. ctypes.wintypes
其定义了许多Windows API常用的数据类型,如HWND, LPCSTR, UINT等