【问题标题】:Python ctypes usage passing pointersPython ctypes 用法传递指针
【发布时间】:2017-07-06 22:57:54
【问题描述】:

我正在尝试从 python 2.7 中的 C 库调用函数。到目前为止,我对大多数教程或信息感到困惑。

C 函数接受 3 个双精度数(标记为 h、k、l)和 2 个指向双精度数的指针(*p、*q)来迭代求解两个双精度数,为简单起见初始化为 0.0。该函数不返回任何内容,它只是使用指针来修改 p 和 q 的值。

我当前的代码如下:

import ctypes
path = '/foo/bar.so'
_lib = ctypes.CDLL(path)
_lib.solve.argtypes = (ctypes.c_double, ctypes.c_double, ctypes.c_double, ctypes.POINTER(ctypes.c_double), ctypes.POINTER(ctypes.c_double))

def py_solve(h, k, l):
    global _lib
    p, q = ctypes.c_double(0.0), ctypes.c_double(0.0)
    _lib.solve(ctypes.c_double(h), ctypes.c_double(k), ctypes.c_double(l), ctypes.POINTER(p), ctypes.POINTER(q))
    return float(p), float(q)

我明白了:

'TypeError: must be a ctypes type'

在我的 py_solve 函数中调用 _lib.solve(...)。也许通过使用 ctypes 的 byref() 函数会更简单,但我也不确定如何做到这一点。任何帮助表示赞赏,谢谢。

【问题讨论】:

    标签: python pointers ctypes


    【解决方案1】:

    函数ctypes.POINTER 接受一个ctypes type 的参数。当你在行中使用它时

    _lib.solve.argtypes = (ctypes.c_double, ctypes.c_double, ctypes.c_double, ctypes.POINTER(ctypes.c_double), ctypes.POINTER(ctypes.c_double))
    

    这正是你正在做的,因为 ctypes.c_double 是一个类型

    稍后你会这样称呼它:

    ctypes.POINTER(p)
    

    参数不是一个类型,而是一个类型的实例——一个已经初始化的ctypes.c_double类型的变量。

    您需要做的就是创建一个指向已经初始化的变量 p 和 q 的指针。只需将ctypes.POINTER(p) 替换为ctypes.byref(p)

    【讨论】:

    • 谢谢。解释得很好,现在一切都说得通了。
    • 请注意,byref 本身并不创建 ctypes 指针,这与 ctypes.pointer 或实例化指针类型不同。 byref直接引用ctypes对象的buffer,比创建ctypes指针效率高。
    • 在这一点上另见this documentation section
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-11-04
    • 1970-01-01
    • 1970-01-01
    • 2017-11-24
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多