python与C++交互

python和C++能进行有效的交互,c++调用Python的一些小用法

写了一个python脚本导入发生异常,可能是编码问题(如存在中文),
Python默认的是ASCII
可加上:
#!/usr/bin/python
# -*- coding: utf-8 -*-
参见:https://www.python.org/dev/peps/pep-0263/

定义类C数据结构:
class Point(Structure):
_pack_ = 1
_fields_ = [('x', c_uint8),
('y', c_uint8),
]
定义点数组初始化:
pointList = [Point(0,0),
Point(1,1),
]
访问:pointList[i].x, pointList[i].y
也可强制转换为指针访问
pPoint = cast(addressof(point),POINTER(Point))
指针有一个属性contents为实例对象
pPoint.contents.x, pPoint.contents.y

想要定义数组:
class Array(Structure):
_pack_ = 1
_fields_ = [('iArray', c_uint8 * 5),
('bArray', c_ubyte * 5),
]
定义缓冲区:
buf = c_buffer("Hello",520)
buf = create_string_buffer("Hello", 10)
第二个是新一点的,旧的也可以用

ctypes的数据类型:https://docs.python.org/2/library/ctypes.html#ctypes.c_ubyte

addressof(obj): 获取ctypes类型地址
byref(obj, offset):
返回ctypes类型轻量级指针
对应以下C代码:(((char *)&obj) + offset)
sizeof: 计算变量和类型的字节数

调用c库的一些函数:
libc = cdll.msvcrt
fopen = libc.fopen
fwrite = libc.fwrite
fclose = libc.fclose
fseek = libc.fseek
fread = libc.fread
ftell = libc.ftell
memset = libc.memset
memcpy = libc.memcpy
可获取函数地址,调用与C一样,注意这些函数操作需要地址
可以用addressof获取ctypes类型的地址

接收C++传来的参数:
如果传过来的是Unicode字符需要转换为python字符串,否则会出现意想不到的错误
虽然用打印和写入文件的方式写入param内容是正确的,但是实际调用libc库时仍会
找不到路径
str(unicode(param))

使用python时如果更加了解其内在机制,会对使用该语言更有帮助

下面上代码:

 1 #!/usr/bin/python
 2 # -*- coding: utf-8 -*-
 3 import os, sys
 4 from ctypes import *
 5 
 6 class CPoint(Structure):
 7     _pack_ = 1
 8     _fields_ = [('x', c_uint8),
 9                 ('y', c_uint8),
10                 ]
11     
12 class CArray(Structure):
13     _pack_ = 1
14     _fields_ = [('iArray', c_uint8 * 5),
15                 ('bArray', c_char * 5),
16                 ]
17     
18 def EditBuf(buf, len):
19     tmp = buf
20     i = 0
21     val = c_char('7')
22     while i < len:
23         memmove(addressof(tmp)+i,addressof(val),sizeof(val))#addressof(tmp)+i相当于指针移位
24         i += 1
25 
26 libc = cdll.msvcrt
27 fopen = libc.fopen
28 fwrite = libc.fwrite
29 fclose = libc.fclose
30 fseek = libc.fseek
31 fread = libc.fread
32 ftell = libc.ftell
33 memset = libc.memset
34 memcpy = libc.memcpy
35 
36 if __name__ == '__main__':
37     point = CPoint(5,6)
38     pPoint = cast(addressof(point),POINTER(CPoint))
39     print "point.x = %d , point.y = %d" %(point.x, point.y)
40     print "pPoint.x = %d , pPoint.y = %d" %(pPoint.contents.x, pPoint.contents.y)
41     print point, pPoint.contents#这里两个地址值不一样说明系统为pPoint新申请了一个Point保存复制的值
42 
43     pointList = [CPoint(0,1),
44                  CPoint(2,3)
45                  ]    
46     print pointList[0].x, pointList[0].y#数组
47 
48     iArr = (c_uint8 * 5)(5,6,7,8)
49     bArr = (c_char * 5)('a','b','c')
50     print bArr[:]
51     cArray = CArray(iArr, bArr[:])#c_uint8和c_char赋初始值的方式不同,具体还没研究
52     print cArray.iArray[:]
53     print cArray.bArray[:]
54 
55     buf = c_buffer("12345",8)#类似c_char*8
56     print buf.value
57     EditBuf(buf,8)#修改buf值,对内存修改
58     print buf.value
59     memmove(addressof(buf),byref(c_char('a')),sizeof(c_char))
60     print buf.value
61 
62     #C库函数调用
63     fp =fopen("D:\\pythonCallClib.txt","wb+")
64     fwrite(buf,1,sizeof(buf),fp)#77777777
65     fseek(fp,3,0)
66     fwrite(addressof(c_char('8')),1,1,fp)
67     fclose(fp)
68 
69     #sizeof
70     print "c_uint8 = %d bytes, c_int = %d bytes, buf = %d bytes" %(sizeof(c_uint8), sizeof(c_int), sizeof(buf))
71 
72     #cast 可以将buf强制转换成我们自定义的类型
73     buf = create_string_buffer("abc",8)
74     p = cast(addressof(buf),POINTER(CPoint))
75     print p.contents.x, p.contents.y
76     

posted @ 2016-04-02 10:59  george_cw  阅读(1740)  评论(0编辑  收藏  举报