Retain reference to a struct

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • andychambers2002@yahoo.co.uk

    Retain reference to a struct

    Hi All,

    A C library I'm using has a number of functions that all require a
    struct as an argument. The example module shows how to make a new
    Python Object from C code and I've seen other posts that recommend this
    way of doing it.

    In this case though, it would seem easier if I could create the object
    in the Python code. This would require storing a pointer to an
    instance of the struct until a certain function is called.

    I can get the pointer into the python code, but whenever I try to use
    it to call another function, the module segfaults. Can anyone suggest
    why this is?

    static PyObject *
    libpyq_PQconnec tdb(PyObject *self, PyObject *args)
    {
    PGconn *conn = PyMem_New(PGcon n, sizeof(PGconn *));
    conn = (PGconn *)PQconnectdb(( const char*)
    PyString_AS_STR ING(args));

    printf("%p", conn);
    return PyLong_FromVoid Ptr(conn) ;
    }

    static PyObject *
    libpyq_PQfinish (PyObject *self, PyObject *args)
    {
    printf("%p", args);
    return 1;
    }
    [color=blue][color=green][color=darkred]
    >>> import libpyq #works fine
    >>> conn = libpyq.PQconnec tdb #conn now a pointer
    >>> libpyq.PQfinish (conn) #segfaults[/color][/color][/color]

    I'm new to C but relatively experienced with Python. I have a sneaky
    suspiscion there's a good reason for not doing it this way but I
    haven't seen a good explanation of why not yet. If you know one,
    please tell me.

    Thanks,
    Andy

  • Carsten Haese

    #2
    Re: Retain reference to a struct

    On Wed, 2005-11-02 at 16:23, andychambers200 2@yahoo.co.uk wrote:[color=blue]
    > Hi All,
    >
    > A C library I'm using has a number of functions that all require a
    > struct as an argument. The example module shows how to make a new
    > Python Object from C code and I've seen other posts that recommend this
    > way of doing it.
    >
    > In this case though, it would seem easier if I could create the object
    > in the Python code. This would require storing a pointer to an
    > instance of the struct until a certain function is called.
    >
    > I can get the pointer into the python code, but whenever I try to use
    > it to call another function, the module segfaults. Can anyone suggest
    > why this is?
    >
    > static PyObject *
    > libpyq_PQconnec tdb(PyObject *self, PyObject *args)
    > {
    > PGconn *conn = PyMem_New(PGcon n, sizeof(PGconn *));
    > conn = (PGconn *)PQconnectdb(( const char*)
    > PyString_AS_STR ING(args));
    >
    > printf("%p", conn);
    > return PyLong_FromVoid Ptr(conn) ;
    > }
    >
    > static PyObject *
    > libpyq_PQfinish (PyObject *self, PyObject *args)
    > {
    > printf("%p", args);
    > return 1;[/color]

    What exactly do you think you're returning here? The function
    declaration says that you're supposed to return a pointer to a PyObject.
    '1' is not likely to be a valid pointer to anything.
    [color=blue]
    > }
    >[color=green][color=darkred]
    > >>> import libpyq #works fine
    > >>> conn = libpyq.PQconnec tdb #conn now a pointer[/color][/color][/color]

    Are you sure that's the correct example code? As written, that line
    doesn't call the PQconnectdb function. It assigns "conn" to be an
    alternate name for the PQconnectdb function.
    [color=blue][color=green][color=darkred]
    > >>> libpyq.PQfinish (conn) #segfaults[/color][/color][/color]

    That's probably due to the fact that the python interpreter wants to
    look up your return value for printing it, but you're returning a bogus
    pointer.
    [color=blue]
    > I'm new to C but relatively experienced with Python. I have a sneaky
    > suspiscion there's a good reason for not doing it this way but I
    > haven't seen a good explanation of why not yet. If you know one,
    > please tell me.[/color]

    The idea of passing around pointers as numbers is very unpythonic. There
    is no guarantee that the number that's passed into PQfinish actually
    came from a call to PQconnectdb. The user could pass in any integer and
    (probably successfully) attempt to crash the system. You should really
    wrap the C struct (or the pointer to the C struct) into a Python object
    instead.

    By the way, it looks like you're trying to write some sort of database
    access module. The 'pq' looks suspiciously like it's for PostgreSQL. If
    that's the case, can't you just use an existing module for connecting to
    PostgreSQL?

    HTH,

    Carsten Haese.


    Comment

    Working...