2017-07-06 78 views
0

我想从python 2.7中的C库调用函数。我对目前为止发现的大多数教程或信息感到困惑。为了简单起见,C函数需要3个双精度值(标记为h,k,l)和2个指向双精度值(* p,* q)的指针来迭代求解两个双精度值,用0.0初始化这个双精度元组。该函数什么都不返回,它只是使用指针来修改p和q的值。Python ctypes用法传递指针

我当前的代码如下:

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()函数来简化,但我不确定如何做到这一点。任何帮助表示赞赏,谢谢。

回答

1

函数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)) 

这就是你做什么用,因为ctypes.c_double是

当以后你这样称呼它:

ctypes.POINTER(p) 

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

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

+0

谢谢。很好的解释,事情现在有道理。 – MrSwordFish

+0

请注意,'byref'本身不会创建ctypes指针,不像'ctypes.pointer'或实例化指针类型。 'byref'直接引用ctypes对象的缓冲区,这比创建ctypes指针更有效。 – eryksun