[Pyrex] Pyrex and char *x[]
Georg Grabler
ggrabler at gmail.com
Wed May 16 09:03:37 UTC 2007
Hello, first of all - thank youf or this very detailed answer on my
question. It helped me out a little, but i now want to give code
examples. Since it's oss anyway (currently trying a python binding for
libalpm, the arch linux package manager, with a own API interface, not
reflecting the crappy original one .. and the original one is really
something to hate).
To the garbage collection issue: It makes me think a little about my
garbage collection at all. My current code structure works fine, don't
really want to run into troubles with this, so i wanted to ask
further, and i don't expect the garbage collection running while i'm
just running test scripts.
The current addList function defines as follows (different name ofc):
def addIgnorePkg(self, char *in_pkgname):
cdef t_config.pyalpm_list *ptr
if self.IgnorePkg != NULL:
ptr = self.IgnorePkg
while ptr.next != NULL:
ptr = ptr.next
ptr.next = <t_config.pyalpm_list *> malloc(sizeof(pyalpm_list))
ptr.next.last = ptr
ptr = ptr.next
ptr.next = NULL
ptr.pkgname = in_pkgname
else:
self.IgnorePkg = <t_config.pyalpm_list *> malloc(sizeof(pyalpm_list))
self.IgnorePkg.pkgname = in_pkgname
self.IgnorePkg.next = NULL
self.IgnorePkg.last = NULL
return
def addIgnorePkgList(self, ignorelist):
cdef char *cString
cdef char *copy
cdef int length
for pyString in ignorelist:
self.addIgnorePkg(pyString)
return
def remIgnorePkg(self, char *in_pkgname):
cdef t_config.pyalpm_list *ptr
if self.IgnorePkg == NULL:
return 1
Accordingly, on destruction time the list self.IgnorePkg is iterated,
and the objects destroyed, by using
def remIgnorePkg(self, char *in_pkgname):
cdef t_config.pyalpm_list *ptr
if self.IgnorePkg == NULL:
return 1
ptr = self.IgnorePkg
while ptr != NULL:
if ptr.pkgname == in_pkgname:
if (ptr.next != NULL):
ptr.next.last = ptr.last
if (ptr.last != NULL):
ptr.last.next = ptr.next
if self.IgnorePkg == ptr and self.IgnorePkg.next != NULL:
self.IgnorePkg = self.IgnorePkg.next
self.IgnorePkg.last = NULL
ptr.next = NULL
ptr.last = NULL
free(ptr)
if ptr == self.IgnorePkg:
self.IgnorePkg = NULL
ptr = NULL
return 0
ptr = ptr.next
return 1
Since i'm experiencing problems with the memcpy, i didn't use it. Does
this mean, that i actually could come into troubles for python
releasing my objects in the structure? Doesn't pyrex tell python that
the object is still in use?
To be true, the malloc:
I used the following structure you wrote, which gave me the error that
the void* can't be converted into a char*
copy = memcpy(copy, cString, length)
So i casted the memcpy result
copy = <char*> memcpy(copy, cString, length)
resultin in
new1 ���
new2 ���
new3 ���
new4 ���
what's quite strange. So well, it did not work out, since the values
were new1, new2, new3, new4. After the copy, by printing the values, i
got the following (even more strange output)
oew4 ���
stdout
stdout
stdout
By using the structure above, it works flawlessly.
I've attached the current config.pyx file to the e-mail, sometimes
it's easier to see the whole thing.
Thank you,
Georg
On 5/16/07, Matt Hammond <matt.hammond at rd.bbc.co.uk> wrote:
> On Wed, 16 May 2007 06:29:41 +0100, Georg Grabler <ggrabler at gmail.com>
> wrote:
>
> > Hello everybody.
> >
> > I want an array to be passed to a function, so basically i started the
> > function as follows:
> >
> > def addToList (self, char *array[]):
> > ....
> >
> > This throws an error compiling:
> > "Cannot convert Python object argument to type 'char(*(*))'"
>
> Functions and classes defined python style (without a "cdef" prefix) are
> made available to python and therefore can only deal with python objects -
> which c-style arrays are not. Similarly c-style strings are not the same
> as python strings.
>
> Could you give a simple example of how you would use addToList from
> python? Would you be passing it something like a list or tuple, or using a
> library defined specialist array type?
>
> Assuming you'd be passing it a list/tuple, eg:
>
> items=["hello","doctor","yesterday","tomorrow","continue"]
> X.addToList(items)
>
> There is also the complication, since you're dealing with strings, of
> handling garbage collection issues: if you don't copy the string data out
> of the python string object, you need to inform python that you're still
> using that object, otherwise it may get garbage collected and the storage
> containing the string might be re-used!
>
> Of course, the simplest, though not necessarily most efficient, solution
> is to copy the string data out of the string into a newly allocated
> character array.
>
> If you want to declare c datatypes, or functions with c datatype
> arguments, then they need to be prefixed with cdef; and they will not be
> accessible from python (the specific variables, functions or classes
> declared with cdef)
>
>
> Here's roughly what I end up doing (in the .pyx file):
>
>
> cdef extern from "string.h":
> cdef void *memcpy(void *, void *, int)
>
>
> class MyClass:
>
> def addToList(self, listitems):
> cdef char *cString
> cdef char *copy
> cdef int length
>
> for pyString in listitems:
> cString = pyString # pyrex auto converts
> length = len(pyString)
>
> # now make our own copy of the string data
> copy = memcpy(copy, cString, length)
>
> self.addList(copy)
>
>
> cdef addList(self, char *str):
> # your code
>
> Caveat: I've not tested this code above; but as I said, I've found this
> general approach works for me.
>
> Remember python string's don't use null termination conventions, so if
> you're retrieving them from your list for later use, you probably also
> need to store the length of the string somewhere too. Hope that's not
> teaching you to suck eggs :-)
>
>
> Hope this helps
>
>
> Matt
> --
> | Matt Hammond
> | Research Engineer, FM&T, BBC, Kingswood Warren, Tadworth, Surrey, UK
> | http://kamaelia.sf.net/
> | http://www.bbc.co.uk/rd/
>
> _______________________________________________
> Pyrex mailing list
> Pyrex at lists.copyleft.no
> http://lists.copyleft.no/mailman/listinfo/pyrex
>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: config.pyx
Type: text/x-csrc
Size: 1892 bytes
Desc: not available
Url : http://lists.copyleft.no/pipermail/pyrex/attachments/20070516/14b0fcf9/attachment.bin
More information about the Pyrex
mailing list