ctypes: Setting callback functions in C libraries

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • sjdevnull@yahoo.com

    #1

    ctypes: Setting callback functions in C libraries

    Hey,

    I'm trying to wrap GNU readline with ctypes (the Python readline
    library doesn't support the callback interface), but I can't figure out
    how to set values to a variable inside the library. This is Python 2.5
    on Linux. Here's what I have so far--if you comment out the memmove
    call (3 lines) it works as expected:

    # START
    #!/usr/local/bin/python2.5
    import ctypes

    ctypes.cdll.Loa dLibrary("libcu rses.so")#, mode=ctypes.RTL D_GLOBAL)
    ctypes.CDLL("li bcurses.so", mode=ctypes.RTL D_GLOBAL)
    ctypes.cdll.Loa dLibrary("libre adline.so")
    readline = ctypes.CDLL("li breadline.so")

    RL_COMPLETION_F UNC_T =
    ctypes.CFUNCTYP E(ctypes.POINTE R(ctypes.c_char _p),
    ctypes.c_char_p , ctypes.c_int, ctypes.c_int)
    RL_LINE_BUFFER = ctypes.c_char_p .in_dll(readlin e, "rl_line_buffer ")
    RL_ATTEMPTED_CO MPLETION_FUNCTI ON =
    RL_COMPLETION_F UNC_T.in_dll(re adline,

    "rl_attempted_c ompletion_funct ion")

    def our_complete(te xt, start, end):
    print "Test", text, start, end
    rv = None
    arrtype = ctypes.c_char_p *4
    globals()["rv"] = arrtype("hello" , "hatpin", "hammer", None)
    globals()["crv"]=ctypes.cast(rv , ctypes.POINTER( ctypes.c_char_p ))
    return rv
    ourfunc = RL_COMPLETION_F UNC_T(our_compl ete)

    _readline = readline.readli ne
    _readline.argty pes = [ctypes.c_char_p]
    _readline.resty pe = ctypes.c_char_p

    ctypes.memmove( ctypes.addresso f(RL_ATTEMPTED_ COMPLETION_FUNC TION),
    ctypes.addresso f(ourfunc),
    4)
    line = _readline("Inpu t: ")
    print "INPUT was: ", line
    #END

    I need to assign ourfunc to RL_ATTEMPTED_CO MPLETION_FUNCTI ON, but
    obviously simple assignment rebinds the name rather than assigning it
    to the C variable.

    Using ctypes.memmove to overwrite it(as I have here) will run the
    function but segfault when ourfunc goes to return (poking around with
    the debugger shows it's dying in ctypes' callbacks.c at line 216, "keep
    = setfunc(mem, result, 0);" because setfunc is NULL). I'm not entirely
    sure that's not because of some error in the prototyping or restype
    setting rather than as a result of memmove, but the memmove seems
    sketchy enough (only sets the function pointer itself presumably, not
    anything that ctypes wrappers need) that I'm looking for a better way
    to do it.

    As it is, returning rv directly or simply returning None causes the
    same segfault.


    Any ideas?

    Thanks very much for your time!

  • sjdevnull@yahoo.com

    #2
    Re: ctypes: Setting callback functions in C libraries

    I realized my wrapping was broken, fixing that below...

    On Jan 25, 12:47 am, "sjdevn...@yaho o.com" <sjdevn...@yaho o.com>
    wrote:
    I'm trying to wrap GNU readline withctypes(the Python readline
    library doesn't support the callback interface), but I can't figure out
    how to set values to a variable inside the library. This is Python 2.5
    on Linux. Here's what I have so far--if you comment out the memmove
    call (3 lines) it works as expected:
    [SNIP]
    I need to assign ourfunc to RL_ATTEMPTED_CO MPLETION_FUNCTI ON, but
    obviously simple assignment rebinds the name rather than assigning it
    to the C variable.
    >
    Usingctypes.mem move to overwrite it(as I have here) will run the
    function but segfault when ourfunc goes to return (poking around with
    the debugger shows it's dying inctypes' callbacks.c at line 216, "keep
    = setfunc(mem, result, 0);" because setfunc is NULL). I'm not entirely
    sure that's not because of some error in the prototyping or restype
    setting rather than as a result of memmove, but the memmove seems
    sketchy enough (only sets the function pointer itself presumably, not
    anything thatctypeswrapp ers need) that I'm looking for a better way
    to do it.
    >
    As it is, returning rv directly or simply returning None causes the
    same segfault.
    >
    Any idea?
    >
    Thanks very much for your time!
    # START
    #!/usr/local/bin/python2.5
    import ctypes

    ctypes.cdll.Loa dLibrary("libcu rses.so")#, mode=ctypes.RTL D_GLOBAL)
    ctypes.CDLL("li bcurses.so", mode=ctypes.RTL D_GLOBAL)
    ctypes.cdll.Loa dLibrary("libre adline.so")
    readline = ctypes.CDLL("li breadline.so")

    RL_COMPLETION_F UNC_T = \
    ctypes.CFUNCTYP E(ctypes.POINTE R(ctypes.c_char _p),
    ctypes.c_char_p , ctypes.c_int, ctypes.c_int)
    RL_LINE_BUFFER = ctypes.c_char_p .in_dll(readlin e, "rl_line_buffer ")
    RL_ATTEMPTED_CO MPLETION_FUNCTI ON = \
    RL_COMPLETION_F UNC_T.in_dll(re adline,
    "rl_attempted_c ompletion_funct ion")

    def our_complete(te xt, start, end):
    print "Test", text, start, end
    rv = None
    arrtype = ctypes.c_char_p *4
    globals()["rv"] = arrtype("hello" , "hatpin", "hammer", None)
    globals()["crv"]=ctypes.cast(rv , ctypes.POINTER( ctypes.c_char_p ))
    return rv
    ourfunc = RL_COMPLETION_F UNC_T(our_compl ete)

    _readline = readline.readli ne
    _readline.argty pes = [ctypes.c_char_p]
    _readline.resty pe = ctypes.c_char_p

    ctypes.memmove( ctypes.addresso f(RL_ATTEMPTED_ COMPLETION_FUNC TION),
    ctypes.addresso f(ourfunc),
    4)
    line = _readline("Inpu t: ")
    print "INPUT was: ", line
    #END

    Comment

    Working...