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!
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!
Comment