2011-09-13 2 views
4

MyDllのc関数をPythonに拡張するためにctypesを使用しています。ctypesを通じてPythonに返されたオブジェクトのメモリを解放する

さらに.pyファイルにあります。私はクラスがあり、そのメソッドは、MyDllの関数をctypesを通じて呼び出します。

Class MyTestClass: 
     def __init__(self,id): 
      libA.MyTestClassInDLL_new.restype = ctypes.c_void_p 
      self.obj = libA.MyTestClassInDLL_new(id) 

MyTestClassInDLL_newとしてMYDLLで定義されている対応するC関数 - 私は私のVC++のdllでこのオブジェクトをインスタンス化する新しいを使用して、そのポインタを返すのです

extern "C" __declspec(dllexport) void * MyTestClassInDLL_new(char* id) 
{ 
    pTestObject = new CMyTestClassInDLL(CString(id)); 
    return (void *)pTestObject;  
} 

注意。私はこの関数のrestypeをctypes.c_void_pとして.pyファイルに設定しました。

私は実行スクリプトには、次のものが含まれています -

testob = MyTestClass("5") 

これが正常に動作します。ここで取得したtestobは、内部的にMyDllからc関数を呼び出すメソッドを呼び出すためにさらに使用されます。

ただし、オブジェクトはMyDllでnewを使用して作成され、MyTestClassInDLL_new()関数によって返されました。このオブジェクトはどのように破壊されますか?どこかでdelete pTestObjectを使用してデストラクタを呼び出し、クリーンアップとメモリの割り当てを解除する必要があります。

答えて

3

私は通常、ポインタを渡して削除するextern destroyオブジェクト関数を追加してこれを処理します。

CPP:

SomeClass* createObj() 
{ 
    return new SomeClass(); 
} 

void destroyObj(SomeClass* pObj){ 
    delete pObj; 
    pObj = NULL; 
} 

H:

extern "C" { 
    SomeClass* createObj(); 
    void destroyObj(SomeClass*); 
} 

PY:

class SomeObj: 
    def __init__(self): 
     self.soLib = cdll.LoadLibrary(PATH_SO) 
     _createObj = self.soLib.createObj 
     _createObj.restype = POINTER(c_long) 

     self._objRef = _createObj() 
     ## do stuff with self._objRef 

    def __del__(self): 
     self.soLib.destroyObj(self._objRef) 
+0

私は正確に同じことを行っています。問題は__del__がスクリプトの実行の最後に呼び出されないということです。どのようにすれば、testobがスコープから外れた後で__del__が呼び出されることを保証できますか(つまり、スクリプトが終了しますか?)testob = Noneは、スクリプトの最後に__del__を呼び出します。それは正しい方法ではないかもしれません。 – Abhaya

+0

スクリプトが終了すると、メモリがクリーンアップされます。それが気になるならば、del関数を明示的に呼び出す:del testob。 – Mark

関連する問題