[Pyrex] access to Modules/*.c or ignoring void**/char** casts

David M. Cooke cookedm at physics.mcmaster.ca
Fri Mar 25 03:08:26 CET 2005


Josiah Carlson <jcarlson at uci.edu> writes:

> Hey everyone,
>
> I'm kind of new to Pyrex (only a few weeks), and I've been struggling
> with this for a few days now, so I thought I would ask a group that
> should probably know the answer...
>
> Essentially, I'd like to dig into a memory mapped file object (mmap) so
> that I don't have to use the (slow) API.
>
> Problem 1:
> Memory mapped file objects are defined in mmapmodule.c, which has no
> includable header file.  There exists mmap.lib in the libs path, and
> mmap.pyd in the dll path (I'm running windows), and the build process
> properly includes the lib path, but I am unable to get it to include
> anything sufficient (I get either "can't find mmap.lib|mmap.pyd" or
> "cannot resolve symbol _mmap_buffer_getwritebuf").
>
> Question 1:
> How does one gain access to functions defined in mmapmodule.c, or any
> function defined in any of the Python source Modules/*.c files?

You can't. The functions in mmap, for instance, are declared static,
so they can't be called from outside the file.

Now, a hacky way to get access to the mmap object would be to define
the mmap_object from the mmapmodule.c file in your own header file,
and cast a Python object you're sure is an mmap object to that struct.
Then you can access the fields (like the data etc).

> Problem 2:
> For my problem, there is always the buffer interface: get a read-write
> buffer, then get the char* from the buffer.  Great, except for one
> problem, in the buffer object definition...
>     int get_buf(PyBufferObject, void **, int *)
> ...takes a void** where it assigns the char* to the data.  When I try to
> use this, I get Pyrex errors of the form:
>     Cannot assign type 'char (*(*))' to 'void (*(*))'
>
> Question 2:
> How would one tell Pyrex "don't worry about char**/void** casting", or
> its equivalent?

Where's get_buf from? For what you'd want, I'd probably do something like

cdef extern from "Python.h":
    int PyObject_AsWriteBuffer(object obj, void **buffer, int *buffer_len)

cdef int get_buffer(obj, char **data, int *length) except -1:
    cdef int result
    cdef void *vd
    # use a void *
    result = PyObject_AsWriteBuffer(obj, &vd, length)
    data[0] = <char *>vd
    return result

Note we call PyObject_AsWriteBuffer with a void *, then cast it back
to char *.

Alternatively, you could just use char ** as the type of the buffer
argument in the cdef extern block (Pyrex won't complain, as it doesn't
know what to check against).

-- 
|>|\/|<
/--------------------------------------------------------------------------\
|David M. Cooke                      http://arbutus.physics.mcmaster.ca/dmc/
|cookedm at physics.mcmaster.ca



More information about the Pyrex mailing list