tags:

views:

81

answers:

3

Consider the following python ctypes - c++ binding:

// 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)

What's the best way to delete the c++ object, when the python object is not needed any more.

[edit] I added the delete function that was suggested, however the problem remains by whom and when the function is called. It should be as convenient as possible.

+1  A: 

In general, dlls should provide a method for cleaning up object that they created. That way, memory allocation is encapsulated within the dll. This means, your dll should probably expose a method like void A_delete(A*).

Space_C0wb0y
+3  A: 

You could implement the __del__ method, which calls a destructor function you would have to define:

// 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)

Also note that you left out the self parameter on the __init__ method.

Some think __del__ is evil. As an alternative, you can use with syntax:

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()
Marcelo Cantos
When will the __del__ function be called?
tauran
When `A`'s reference count hits zero, just before the object is cleaned up.
Marcelo Cantos
Are there any guarantees on when that happens? Can't find them in the python documentation. Does this mean python decides when `__del__` is executed?
tauran
@tauran: See [this](http://docs.python.org/glossary.html#term-reference-count) and [this](http://docs.python.org/release/2.5.2/ext/refcounts.html) for information about reference counts
Space_C0wb0y
@Marcelo Cantos: +1 I really like this use of `with` here.
Space_C0wb0y
A: 

Export a function from the DLL the frees the object. You have to do this in order to ensure that the same memory management mechanism is used to free the object that was in charge when the object was allocated.

Jim Brissom