【问题标题】:Pointers and arrays in Python ctypesPython ctypes 中的指针和数组
【发布时间】:2010-11-24 16:35:39
【问题描述】:

我有一个包含 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?

【问题讨论】:

    标签: python arrays pointers ctypes


    【解决方案1】:

    您可以使用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>
    >>> 
    

    【讨论】:

    • 我用过ctypes几次,之前在链接文档中遇到过。
    • 为什么我是LP_c_ulong 对象而不是LP_c_ulong_Array_5 对象
    • LP_c_ulong_Array_5 将是一个地址,该地址指向一个指向uint32s 数组中第一个元素的地址,而 OP 的函数正在寻找一个指向第一个元素的地址大批。 LP_c_ulong_Array_5 将用于如下功能:int c_read_block(uint32 addr, uint32 *buf[], uint32 num);
    【解决方案2】:

    您可以转换结果,但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】:

      解决方案中有错字。为了获得指向 ulongs 数组的指针,您需要强制转换为 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>
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-01-23
        • 1970-01-01
        • 2011-05-24
        • 2017-11-24
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多