2017-07-06 77 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