2016-06-13 6 views
0

コードのクリーンアップのために、私のC構造体用の自動生成ctypesラッパーをPython専用の拡張機能から分離したい)。ctypes.Structureから継承したクラスのサブクラスを渡す

サブクラス化構造を自動生成したバインディングに渡すのに問題があります。これを行う方法はありますか?

// C Code 
typedef struct CStruct 
{ 
    int value; 
} CStruct; 

int CFunc(const CStruct **pCStruct); 

自動生成されたPythonバインディング:

# Python Implementation 
import ctypes 
class PyStruct(ctypes.Structure) 
    _fields_ = ['value', ctypes.c_int32] 

pyfunc = dll.CFunc 
pyfunc.argtypes = (ctypes.POINTER(ctypes.POINTER(PyStruct)),) 
pyfunc.restype = ctypes.c_int32 

私のバインディングからサブクラスを作成し、私のFUNCに渡す試してみてください。ここでは

class PySubStruct(PyStruct): 
    def __init__(self, *args, **kwargs): 
     super(PySubStruct, self).__init__(*args, **kwargs) 

    def value_mult(self, factor): 
     return self.value * factor 

# Works great 
structptr = ctypes.pointer(PyStruct()) 
result_A = pyfunc(ctypes.byref(structptr)) 

# Create an instance of substruct and call the c-func. 
# Raises exception 
substructptr = ctypes.pointer(PySubStruct()) 
result_B = pyfunc(ctypes.byref(substructptr)) 

は例外です:

ctypes.ArgumentError: argument 3: <type 'exceptions.TypeError'>: 
    expected LP_LP_PyStruct instance instead of 
    pointer to LP_PySubStruct 

方法はありますか自動生成バインディングや "monkey-patching"を変更せずにこれを行うには?

コメントで要求されたよう
+0

はctypes'だけでは、 "Cタイプ" である 'のように見えます。サブクラス化についてはわかりません。 'ctypes.cast'が役に立ちます。 –

+0

ありがとうございました!私はctypes.castを見ました。残念ながら、ドキュメントとサンプルはかなり不足していました。私は様々なTypeErrorsを得続けました。上のコンテキストでキャストを使用する方法のきれいな例があれば、それは非常に役立つでしょう。現時点では、私は単に引数としてctypes.Structureを消費し、拡張するのではなく、その上に接続する完全な並列クラスを作成しています。 – destructo

答えて

1

、ここctypes.castを使った例です:

関連する問題