[Cython] Cannot convert pointer to Python Object
Robert Bradshaw
robertwb at math.washington.edu
Thu Jul 23 21:28:37 CEST 2009
On Jul 23, 2009, at 12:10 PM, Lisandro Dalcin wrote:
> On Thu, Jul 23, 2009 at 10:29 AM, Richard
> Clarke<rsclarke at gmail.com> wrote:
>> Thank you Robert, the explanation on how and where to use cdef was
>> most helpful. I think it has just clicked(with a flag waving
>> 'idiot').
>>
>> The PyCObject concept is a nice idea, removing cdef foo_t *foo from
>> outside of __init__ ? However, I see implications in memory
>> deallocation. How does cython currently handle memory deallocation?
>
> I'm not sure you need PyCObject for your code ...
For sure PyCObject is not needed here. I was musing about a ptr <->
object conversion happening automatically via PyCObject, just as we
handle the more basic numeric types. Deallocation of pointers needs
to be handled by the user explicitly, so perhaps it's not a good idea
to make this transparently easy.
>
>>
>> I assume the best practice would be for users to deallocate memory in
>> the class __del__ method (calling the appropriate wrapped c library
>> destructor).
>
> Yes. More specifically, you should allocate stuff in __cinit__(), and
> deallocate stuff in __dealloc__()...
+1. To clarify, __cinit__ is called exactly once per object creation
(no such guarantee with __init__). Likewise, __dealloc__ is always
called exactly once upon collection. This makes memory management
easy--essentially you're boostrapping of Python's refcounting.
>
>
>> Otherwise does cython simply free(foo) or interprets the
>> language to build a depth first deallocation method?
>
> Cython does not manage memory allocated with malloc()... you have to
> manage deallocation yourself...
>
>
>> I guess it
>> should do the simplest free(foo), if the developer was lazy not to
>> deallocate memory, they can suffer with memory leaks. I think I
>> might
>> have answered my own question here...
>>
>
> In short, you have to modify your class, using something like this
>
> cdef class Bar: # NOTE: "cdef" class
>
> cdef foo_t *c_foo # NOTE: "cdef" instance (not class) member!!!
>
> def __cinit__(self): # NOTE: using "__cinit__", not "__init__"
> self.c_foo = self.c_open()
>
> def __dealloc__(self): # NOTE: using "__dealloc__", not "__del__"
> if self.c_foo != NULL:
> free(self.c_foo)
>
> cdef foo_t* c_open(self): # NOTE: using "cdef", not "def", this
> method will not show-up on Python side, it is a kind of internal,
> private method.
> cdef foo_t *foo = NULL
> foo = init()
> return foo
>
>
> --
> Lisandro Dalcín
> ---------------
> Centro Internacional de Métodos Computacionales en Ingeniería (CIMEC)
> Instituto de Desarrollo Tecnológico para la Industria Química (INTEC)
> Consejo Nacional de Investigaciones Científicas y Técnicas (CONICET)
> PTLC - Güemes 3450, (3000) Santa Fe, Argentina
> Tel/Fax: +54-(0)342-451.1594
> _______________________________________________
> Cython-dev mailing list
> Cython-dev at codespeak.net
> http://codespeak.net/mailman/listinfo/cython-dev
More information about the Cython-dev
mailing list