[Pyrex] Passing references to C "objects,structures,arrays,etc"

Seth Nickell seth at gnome.org
Mon Sep 22 00:47:01 CEST 2003


I'm wrappering the DBus API, which uses a number of complex/annoying
types. I want to write simple converter functions for these which take a
nice Python type and produce an appropriate C type. For example, the
DBus API takes an ordered array of path elements instead of a path
string in a number of places (e.g. "/my/test/path" -> {"my", "test",
"path", NULL}). I don't want to include the code to do this in every
wrapper function that takes a path string and calls a C api that accepts
a path array.

I'd really like to have a function:

def build_parsed_path(path):
    cdef char **cpatharray

    path_element_list = path[1:].split('/')
    
    size = len(path_element_list)
    cpatharray = <char **>malloc(sizeof(char*) * (size + 1))

    for i in range(size):
        path_element = path_element_list[i]
        cpatharray[i] = path_element

    cpatharray[size] = NULL

    return <object>cpatharray

And then on the client side...

cdef char **cpatharray
path_array = build_parsed_path("/my/test/path")
cpatharray = <char**>path_array

But this doesn't work, cpatharray[0] on the client side ends up being
totally different from cpatharray[0] inside build_parsed_path. My guess
is that "cpatharray[i] = path_element" gets a reference to internal
memory of path_element rather than strdup-ing, which is gargbage
collected when path_element_list goes out of scope? 

But also, I wonder if the <char**> -> <object> -> <char**> casting is
the right way to do things.

1) Is there a more natural way to pass around C pointers to functions
and stuff that doesn't require this nasty casting? Is the casting even
valid or is this maybe what's causing the corruption?

2) Is there a way to "ref" Python objects so that they won't be gargbage
collected when there are C pointers pointing to all or pieces of them?

-Seth





More information about the Pyrex mailing list