2010-09-16 150 views
3

考慮以下的Python的ctypes - C++結合:的Python ctypes的,C++對象的破壞

// C++ 
class A 
{ 
public: 
    void someFunc(); 
}; 

A* A_new() { return new A(); } 
void A_someFunc(A* obj) { obj->someFunc(); } 
void A_destruct(A* obj) { delete obj; } 

# python 
from ctypes import cdll 

libA = cdll.LoadLibrary(some_path) 

class A: 
    def __init__(self): 
     self.obj = libA.A_new() 

    def some_func(self): 
     libA.A_someFunc(self.obj) 

什麼是刪除C++對象的最好方式,當不需要Python對象了。

[編輯] 我說有人建議刪除功能,但問題仍然存在由誰來當函數被調用。它應該儘可能方便。

回答

7

您可以實現的__del__方法,它調用析構函數,你必須定義:

C++

class A 
{ 
public: 
    void someFunc(); 
}; 

A* A_new() { return new A(); } 
void delete_A(A* obj) { delete obj; } 
void A_someFunc(A* obj) { obj->someFunc(); } 

的Python

from ctypes import cdll 

libA = cdll.LoadLibrary(some_path) 

class A: 
    def __init__(self): 
     self.obj = libA.A_new() 

    def __del__(self): 
     libA.delete_A(self.obj) 

    def some_func(self): 
     libA.A_someFunc(self.obj) 

還要注意,在上省略了self參數方法。

有些人認爲__del__是邪惡的。作爲替代方案,您可以使用with語法:

class A: 
    def __init__(self): 
     self.obj = libA.A_new() 

    def __enter__(self): 
     return self 

    def __exit__(self): 
     libA.delete_A(self.obj) 

    def some_func(self): 
     libA.A_someFunc(self.obj) 

with A() as a: 
    # Do some work 
    a.some_func() 
+0

何時調用__del__函數? – tauran 2010-09-16 08:42:58

+0

當「A」的引用計數達到零時,就在清理對象之前。 – 2010-09-16 08:44:43

+0

這種情況何時發生?在python文檔中找不到它們。這是否意味着python決定何時執行__del__? – tauran 2010-09-16 08:47:56

2

一般來說,動態鏈接庫應提供清理對象他們創建的方法。這樣,內存分配被封裝在dll中。這意味着,您的dll應該可能會暴露像void A_delete(A*)這樣的方法。

1

出口從DLL將釋放對象的函數。您必須這樣做才能確保使用相同的內存管理機制釋放分配對象時負責的對象。