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.LoadLibrary("libcurses.so")#, mode=ctypes.RTLD_GLOBAL)
ctypes.CDLL("libcurses.so", mode=ctypes.RTLD_GLOBAL)
ctypes.cdll.LoadLibrary("libreadline.so")
readline = ctypes.CDLL("libreadline.so")

RL_COMPLETION_FUNC_T =
ctypes.CFUNCTYPE(ctypes.POINTER(ctypes.c_char_p),
        ctypes.c_char_p, ctypes.c_int, ctypes.c_int)
RL_LINE_BUFFER = ctypes.c_char_p.in_dll(readline, "rl_line_buffer")
RL_ATTEMPTED_COMPLETION_FUNCTION =
RL_COMPLETION_FUNC_T.in_dll(readline,

"rl_attempted_completion_function")

def our_complete(text, 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_FUNC_T(our_complete)

_readline = readline.readline
_readline.argtypes = [ctypes.c_char_p]
_readline.restype = ctypes.c_char_p

ctypes.memmove(ctypes.addressof(RL_ATTEMPTED_COMPLETION_FUNCTION),
               ctypes.addressof(ourfunc),
               4)
line = _readline("Input: ")
print "INPUT was: ", line
#END

I need to assign ourfunc to RL_ATTEMPTED_COMPLETION_FUNCTION, 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!

-- 
http://mail.python.org/mailman/listinfo/python-list

Reply via email to