+ -
当前位置:首页 → 问答吧 → 关于ctypes结构体的指针调用

关于ctypes结构体的指针调用

时间:2010-12-02

来源:互联网

我用ctypes调用一个c的dll,它主要的一个函数通过发送消息给主窗口,然后lParam参数就是一个结构体的指针,最后从这个指针引用结构体获取当中数据!界面我是用pyqt4实现的,已经截获到相应的窗口消息,也从lParam得到指针,不过我把指针转换成 python模拟这个C结构体的类,但是调用不了,相应代码pHeader = cast(msg.lParam, POINTER(StockInterface.RCV_DATA)) 

pHeader是一个LP_RCV_DATA对象,是不是我的思路有错误了!请大哥们指出! 

接口实例 RCV_DATA 是一个C的结构体 
RCV_DATA * pHeader; 
pHeader = (RCV_DATA *)lParam;

作者: samgell   发布时间: 2010-12-02

“调用不了”是什么错误?

作者: iambic   发布时间: 2010-12-02

pHeader是一个LP_RCV_DATA,就是“指针”
pHeader[0]就是一个RCV_DATA, 就是模拟结构的类

但是无论使用pHeader.xxx还是pHeader.xxx
都会发出 object has no xxx attribute的错误

作者: samgell   发布时间: 2010-12-02

pHeader.contents.xxx
pHeader是一个指针,要先使用pHeader.contents拿到指向的对象。以后遇到这种问题你可以自己dir(pHeader)。

作者: iambic   发布时间: 2010-12-02

哦···谢谢iambic···先实践下!

作者: samgell   发布时间: 2010-12-02

还是有这样的错误AttributeError: 'RCV_DATA' object has no attribute 'm_nPacketNum'

这是我的模拟结构体的类
class RCV_DATA(Structure):
  __pack__ = 1
  __fields__ = [
  ("m_wDataType", c_int),('m_nPacketNum', c_int),
  ("m_File", RCV_FILE_HEADEx),("m_bDISK", c_int)
  ]
  class interRCV_DATA(Union):
  __pack__ = 1
  __fields__ = [
  ("m_pReportV2",POINTER(RCV_REPORT_STRUCTExV2)),("m_pReportV3",POINTER(RCV_REPORT_STRUCTExV3)),
  ("m_pDay",POINTER(RCV_HISTORY_STRUCTEx)),("m_pMinute",POINTER(RCV_MINUTE_STRUCTEx)),
  ("m_pPower",POINTER(RCV_POWER_STRUCTEx)),("m_pData",c_void_p)
  ]


这个是操作代码

def winEvent(self, msg):
  if(msg.message != StockInterface.WM_STOCKARRIVE):
  return False, id(msg)
  pHeader = cast(msg.lParam, POINTER(StockInterface.RCV_DATA))
  dataObject = pHeader.contents
  if(msg.wParam == StockInterface.RCV_REPORT):
  for i in range(0, dataObject.m_nPacketNum):  
  pass

作者: samgell   发布时间: 2010-12-02

好难明!按照你的意思dir输入,已经有其他一个内嵌的类interRCV_DATA,但是就读取不了其他attribute

['__class__', '__ctypes_from_outparam__', '__delattr__', '__dict__', '__doc__', '__fields__', '__getattribute__', '__hash__', '__init__', '__module__', '__new__', '__pack__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__str__', '__weakref__', '_b_base_', '_b_needsfree_', '_objects', 'interRCV_DATA']

作者: samgell   发布时间: 2010-12-02

把代码放到里。缩进乱了。

作者: iambic   发布时间: 2010-12-02

把代码放到[code]...[/code]里。缩进乱了。

作者: iambic   发布时间: 2010-12-02

Python code
class RCV_DATA(Structure):
  __pack__ = 1
  __fields__ = [
  ("m_wDataType", c_int),('m_nPacketNum', c_int),
  ("m_File", RCV_FILE_HEADEx),("m_bDISK", c_int)
  ]
  class interRCV_DATA(Union):
  __pack__ = 1
  __fields__ = [
  ("m_pReportV2",POINTER(RCV_REPORT_STRUCTExV2)),("m_pReportV3",POINTER(RCV_REPORT_STRUCTExV3)),
  ("m_pDay",POINTER(RCV_HISTORY_STRUCTEx)),("m_pMinute",POINTER(RCV_MINUTE_STRUCTEx)),
  ("m_pPower",POINTER(RCV_POWER_STRUCTEx)),("m_pData",c_void_p)
  ]

def winEvent(self, msg):
  if(msg.message != StockInterface.WM_STOCKARRIVE):
  return False, id(msg)
  pHeader = cast(msg.lParam, POINTER(StockInterface.RCV_DATA))
  dataObject = pHeader.contents
  if(msg.wParam == StockInterface.RCV_REPORT):
  for i in range(0, dataObject.m_nPacketNum):   
  pass



作者: samgell   发布时间: 2010-12-02

不是为了把代码放到[code]...[/code]里而放到[code]...[/code],而是为了防止缩进错误才把代码放到[code]...[/code]里。你把有错误的代码粘进来,缩进还是错的,没任何意义。

作者: iambic   发布时间: 2010-12-02

Python code

class RCV_DATA(Structure):
    __pack__ = 1
    __fields__ = [
        ("m_wDataType", c_int),('m_nPacketNum', c_int),
        ("m_File", RCV_FILE_HEADEx),("m_bDISK", c_int)
    ]
    class interRCV_DATA(Union):
        __pack__ = 1
        __fields__ = [
            ("m_pReportV2",POINTER(RCV_REPORT_STRUCTExV2)),
            ("m_pReportV3",POINTER(RCV_REPORT_STRUCTExV3)),
            ("m_pDay",POINTER(RCV_HISTORY_STRUCTEx)),
            ("m_pMinute",POINTER(RCV_MINUTE_STRUCTEx)),
            ("m_pPower",POINTER(RCV_POWER_STRUCTEx)),
            ("m_pData",c_void_p)
        ]

def winEvent(self, msg):
    if(msg.message != StockInterface.WM_STOCKARRIVE):
        return False, id(msg)
    pHeader = cast(msg.lParam, POINTER(StockInterface.RCV_DATA))
    dataObject = pHeader.contents
    if(msg.wParam == StockInterface.RCV_REPORT):
        for i in range(0, dataObject.m_nPacketNum):   
            pass





作者: samgell   发布时间: 2010-12-02

__fields__应该是_fields_?

作者: iambic   发布时间: 2010-12-02

另外你的匿名union写法好像不太对。我这边是调不起来。改了下:

Python code
class interRCV_DATA(Union):
    _pack_ = 1
    _fields_ = [
        ("m_pReportV2",POINTER(RCV_REPORT_STRUCTExV2)),
        ("m_pReportV3",POINTER(RCV_REPORT_STRUCTExV3)),
        ("m_pDay",POINTER(RCV_HISTORY_STRUCTEx)),
        ("m_pMinute",POINTER(RCV_MINUTE_STRUCTEx)),
        ("m_pPower",POINTER(RCV_POWER_STRUCTEx)),
        ("m_pData",c_void_p)
    ]
class RCV_DATA(Structure):
    _pack_ = 1
    _anonymous_ = ("u",)
    _fields_ = [
        ("m_wDataType", c_int),('m_nPacketNum', c_int),
        ("m_File", RCV_FILE_HEADEx),("m_bDISK", c_int)
        ('u', interRCV_DATA)
    ]


作者: iambic   发布时间: 2010-12-02

实践下···我以为python所有都系双下划线!

作者: samgell   发布时间: 2010-12-02

双下划线的是python语言的属性,ctypes属于一个库,库级别的属性而非语言级别的属性,所以用了单下划线。

作者: iambic   发布时间: 2010-12-02