Python ctypes 用法传递指针

MrS*_*ish 4 python ctypes pointers

我正在尝试从 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)
Run Code Online (Sandbox Code Playgroud)

我得到:

'TypeError: must be a ctypes type'
Run Code Online (Sandbox Code Playgroud)

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

Pau*_*ius 7

该函数ctypes.POINTER采用一个 ctypes类型的参数。当你在行中使用它时

_lib.solve.argtypes = (ctypes.c_double, ctypes.c_double, ctypes.c_double, ctypes.POINTER(ctypes.c_double), ctypes.POINTER(ctypes.c_double))
Run Code Online (Sandbox Code Playgroud)

这正是你在做什么,因为 ctypes.c_double 是一个type

后来你这样称呼它:

ctypes.POINTER(p)
Run Code Online (Sandbox Code Playgroud)

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

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