2017-07-06 26 views
0

Python 2.7のCライブラリから関数を呼び出そうとしています。私は、これまでに見つけたほとんどのチュートリアルや情報で、むしろ混乱しています。Python ctypes使用法のポインタを渡す

C関数は、単純化のために0.0で初期化された2つの倍精度を反復して解くために、double(* p、* q)への3つの倍精度(h、k、l)この関数は何も返しません。単にポインタを使って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) 

私が手に:私のpy_solve機能に_lib.solve(...)を呼び出す行に

'TypeError: must be a ctypes type' 

を。たぶんこれはctypesのbyref()関数を使う方が簡単になるでしょうが、私はそれをどうやって行うのかも分かりません。どんな助けでも感謝しています。

答えて

1

関数ctypes.POINTERは、タイプの引数をとります。あなたはラインでそれを使用

_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.c_doubleのすでに初期化された変数

ctypes.POINTER(p) 

引数はタイプが、タイプのインスタンスではありません。

あなたがする必要があることは、既に初期化された変数pとqへのポインタを作成することだけです。 ctypes.POINTER(p)ctypes.byref(p)に置き換えてください。

+0

ありがとうございました。非常によく説明されているように、物事は今、意味があります – MrSwordFish

+0

'byref'は、' ctypes.pointer'とは異なり、ポインタ型をインスタンス化するのではなく、ctypesポインタ自体を作成しません。 'byref'はctypesオブジェクトのバッファを直接参照するので、ctypesポインタを作るよりも効率的です。 – eryksun

関連する問題