Python Function pointer in C

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • David Gilbert

    #1

    Python Function pointer in C

    I'm trying to maintain the interface to KQueue for FreeBSD. At one
    point, the C module stores an opaque object in a C structure such that
    the opaque pointer can be used later by the application.

    In Python, I want to say something like:

    kev = [KEvent(1000, filter=EVFILT_T IMER, flags=EV_ADD|EV _ONESHOT,
    udata=lambda x: getJob(x, con))]
    kq.event(kev, 0, 0)

    and later, this is used by

    kev = kq.event(None, 1, 0)
    print "Kevent Triggered! %s" % str(kev)

    # Call event's udata
    kev.udata(kev)

    .... so this doesn't work. Specifically:

    [3:4:304]dgilbert@canoe: ~/devel/SoftGrabber> python
    Python 2.3.4 (#2, Nov 2 2004, 16:03:35)
    [GCC 3.4.2 [FreeBSD] 20040728] on freebsd5
    Type "help", "copyright" , "credits" or "license" for more information.[color=blue][color=green][color=darkred]
    >>> import kqsyscall
    >>> from kqsyscall import *
    >>> kq = kqueue()
    >>> kev = kevent(1000, EVFILT_TIMER, EV_ADD+EV_ONESH OT, 0, 0, lambda x: x+1)
    >>> kev[/color][/color][/color]
    <KQEvent ident=1000 filter=-7 flags=11 fflags=0 data=0 udata=0x81b4fb4 >[color=blue][color=green][color=darkred]
    >>> kev.udata[/color][/color][/color]
    <function <lambda> at 0x81b4fb4>[color=blue][color=green][color=darkred]
    >>> kev.udata(1)[/color][/color][/color]
    Segmentation fault (core dumped)

    Now the code in the C module (kqsyscall above) defines the kevent()
    return as the following object:

    static struct memberlist KQEvent_memberl ist[] = {
    {"ident", T_UINT, OFF(e.ident)},
    {"filter", T_SHORT, OFF(e.filter)},
    {"flags", T_USHORT, OFF(e.flags)},
    {"fflags", T_UINT, OFF(e.fflags)},
    {"data", T_INT, OFF(e.data)},
    {"udata", T_OBJECT, OFF(e.udata)},
    {NULL} /* Sentinel */
    };

    And it also defines various support functions.

    How do I define "udata" such that I can stuff the lambda reference in
    there?

    Now... I've wondered if this is a reference counting issue --- but
    this still happens when I use the name of a module global function as
    udata.

    Dave.

    --
    =============== =============== =============== =============== =============== =
    |David Gilbert, Independent Contractor. | Two things can only be |
    |Mail: dave@daveg.ca | equal if and only if they |
    |http://daveg.ca | are precisely opposite. |
    =============== =============== =============== ============GLO =============== =
  • Nick Coghlan

    #2
    Re: Python Function pointer in C

    David Gilbert wrote:[color=blue]
    > I'm trying to maintain the interface to KQueue for FreeBSD. At one
    > point, the C module stores an opaque object in a C structure such that
    > the opaque pointer can be used later by the application.[/color]

    In this case, a Py_IncRef/DecRef pair is definitely required - the 'borrowed'
    reference from the Python function call only lasts until the function returns.
    You need your own reference if you're going to hang on to the pointer.
    [color=blue]
    > How do I define "udata" such that I can stuff the lambda reference in
    > there?[/color]

    PyObject* should be fine so long as the references are handled correctly.
    [color=blue]
    > Now... I've wondered if this is a reference counting issue --- but
    > this still happens when I use the name of a module global function as
    > udata.[/color]

    I'd suggest adding the IncRef/DecRef pair and trying it out again. I can't see
    anything else obviously wrong in the fragments you've posted.

    If that was the sole problem though, I would have expected the same as you - for
    the module global function to work correctly.

    Sorry I can't be more help. . .

    Cheers,
    Nick.

    Comment

    Working...