代码之家  ›  专栏  ›  技术社区  ›  Andrew Bainbridge

python类型中的指针和数组

  •  35
  • Andrew Bainbridge  · 技术社区  · 15 年前

    我有一个包含C函数的DLL,其原型如下:

    int c_read_block(uint32 addr, uint32 *buf, uint32 num);

    我想用ctypes从python调用它。函数需要一个指向一块内存的指针,将结果写入其中。我不知道如何构建和传递这样一块记忆。ctypes文档没有多大帮助。

    构造一个数组并传递它“byref”,如下所示:

        cresult = (c_ulong * num)()
        err = self.c_read_block(addr, byref(cresult), num)
    

    给出此错误消息:

    ArgumentError: argument 3: <type 'exceptions.TypeError'>: expected LP_c_ulong instance instead of pointer to c_ulong_Array_2

    我想这是因为python ulong数组与c uint32数组完全不同。我应该用吗? create_char_string . 如果是这样,我如何说服python将缓冲区“强制转换”到lp-c-ulong?

    3 回复  |  直到 6 年前
        1
  •  52
  •   Mark Rushakoff    15 年前

    你可以用 cast 功能:

    >>> import ctypes
    >>> x = (ctypes.c_ulong*5)()
    >>> x
    <__main__.c_ulong_Array_5 object at 0x00C2DB20>
    >>> ctypes.cast(x, ctypes.POINTER(ctypes.c_ulong))
    <__main__.LP_c_ulong object at 0x0119FD00>
    >>> 
    
        2
  •  0
  •   ephemer    6 年前

    你可以投射结果,但是 ctypes 允许您直接使用数组代替指针。问题是 byref 在代码中(相当于指向指针的指针):

    因此,而不是:

    cresult = (c_ulong * num)()
    err = self.c_read_block(addr, byref(cresult), num)
    

    尝试:

    cresult = (c_ulong * num)()
    err = self.c_read_block(addr, cresult, num)
    
        3
  •  -1
  •   bemehow    9 年前

    解决方案有错别字。为了获得指向一个ulong数组的指针,需要将其强制转换为 POINTER(list of ulong)

    In [33]: ptr = ctypes.cast(x, ctypes.POINTER(ctypes.c_ulong*5))
    In [34]: ptr
    Out[34]: <__main__.LP_c_ulong_Array_5 at 0x23e2560>