2011-08-09 5 views
1

私はPythonとctypesでラップしたいくつかのデータ型を持つCライブラリを持っています。ctypesからC関数を呼び出す:classインスタンスはNoneになります。

typedef struct type1_struct type1_t; 
typedef struct type2_struct type2_t; 

void some_function(type1_t *t1 , type2_t *t2) { 
    if (t2 == NULL) { 
    // Do whatever 
    } else { 
    // 
    } 
} 

このコードの主なポイントは、そのsome_function(IS)T2引数の値としてNULLを取ることができる:Cで私は、次の(概略)コードを持っています。 Pythonではtype1_tとtype2_tタイプは、クラスタイプ1とタイプ2がfrom_param()メソッド使用でラップされていますので、cfunc_some_function関数は引数としてのType1とType2のインスタンスを取るために初期化され

Class Type1: 
    def from_param(self): 
     return self.c_ptr 


    def call_some_func(self , arg2 = None): 
     # This fails when the python/ctypes tries to 
     # lookup the from_param() method and arg2 is None. 
     cfunc_some_function(self , arg2)  


lib_handle = ctypes.CDLL(lib) 
cfunc_some_function = getattr(lib_handle , "some_function") 
cfunc_some_function.argtypes = [Type1 , Type2] 

を、ctypesの層は、その後呼び出します2つの入力引数のfrom_param()メソッド。しかし、私はType1クラスの 'call_some_func()'メソッドがarg2引数にNoneを受け入れることを望んでいますが、ctypesはNoneオブジェクトのfrom_param()メソッドを呼び出そうとします。

だから私の質問は次のとおりです。ctypes関数呼び出しコードを取得して、None入力引数を取得したときにNULLを渡すことは可能ですか?

ヨアキム

答えて

3

from_param()メソッドはクラスメソッドである必要がありますが、インスタンスメソッドとして定義しています。それをclassmethodに変更し、パラメータがNoneであるかどうかを確認します。 Type2のための

class Type1: 
    @classmethod 
    def from_param(cls, obj): 
     if obj is None: 
      return c_void_p() 
     else: 
      return obj.c_ptr 

と同じ:

(未テスト)のようなものを。

+0

OK;それは面白かったです。私はfrom_param()のインスタンスメソッドとして〜15のケースがあり、それは私にとってうまくいきました(このインスタンスは問題ありません)。私はあなたが示唆したようにそれをうまくいきました。ありがとう! – user422005

+0

ほとんどの場合、 'Type.method(obj)'と 'obj.method()'は互換性があります。 'obj'が' Type'のインスタンスであるときに互換性がありますが、ctypesは 'Type.method obj) 'objが' None'のような別の型で、それがあなたが走っているものです。 – Duncan

+0

@eryksunありがとう:修正済み。だからこそ、私はコードサンプルをテストできないときはいつも「テストされていない」と書いています。 – Duncan

0

たぶん、あなたは、呼び出しの前にタイプ2にNoneを変換することができません:

cfunc_some_function(self , Type2(arg2)) 

とType2.from_param())は、(cfunc_some_functionのための右のオブジェクトを返します。

関連する問題