• 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     

  • 相关阅读:
    POJ 2329 Nearest number
    POJ 2192 Zipper (简单DP)
    POJ 2231 Moo Volume(递推、前缀和)
    数据库增删改查--2017-04-08
    时间戳--2017-04-07
    数据库三大范式---2017-04-07
    数据库主键和外键----数据库基础知识1---2017-04-07
    登录页面(简单版,带遮罩层)---2017-04-06 (与04-05日写的差不多,界面圆滑点)
    第一阶段项目所遇到的问题---2017-04-066
    图片点击轮播(四)高级--2017-04-05
  • 原文地址:https://www.cnblogs.com/george-cw/p/5347104.html
Copyright © 2020-2023  润新知