I'm having problem figuring out how to pass a foreign static pointer to a c
function using cffi.
I use SWIG to generate binding for readline
This is the meta keymap defined in keymap.h
extern KEYMAP_ENTRY_ARRAY emacs_meta_keymap;
which I need to pass as the second argument to
extern int rl_bind_key_in_map PARAMS((int, rl_command_func_t *, Keymap));
In the example below, I can use rl_bind_key without any problem.
(in-package :cl-user)
(cffi:defcallback rl-magic-tab :int ((rep :int) (chord :int))
(rl::rl_insert 1 (char-code #\t))
(rl::rl_insert 1 (char-code #\a)
(rl::rl_insert 1 (char-code #\b))))
CL-USER > (rl_initialize)
CL-USER > (rl::rl_bind_key (char-code #\tab) (cffi:callback rl-magic-tab))
However, when I tried to pass rl::emacs_meta_keymap as is or via (cffi:convert-
to-foreign rl::emacs_meta_keymap :pointer) as the 2nd argument to
rl_bind_key_in_map
I get exceptions (both in lispworks and clisp)
CL-USER > (rl::rl_bind_key_in_map (char-code #\,)
(cffi:callback rl-magic-tab)
(cffi:convert-to-foreign
rl::emacs_meta_keymap :pointer))
Error: Signal B [code 0] at B7FA6C90 {inside foreign code}
eax 0 ; ebx B7FBB42C ; ecx 160 ; edx B7FBB9D4
esp BFADA9A4 ; ebp BFADA9AC ; esi 2004DC82 ; edi B7FBBDE0
1 (abort) Return to level 0.
2 Restart top-level loop.
CL-USER > (rl::rl_bind_key_in_map (char-code #\,)
(cffi:callback rl-magic-tab)
rl::emacs_meta_keymap)
Error: Signal B [code 0] at B7FA6C90 {inside foreign code}
eax 0 ; ebx B7FBB42C ; ecx 160 ; edx B7FBB9D4
esp BFADA8F4 ; ebp BFADA8FC ; esi 2004DC82 ; edi 0
1 (abort) Return to level 0.
2 Restart top-level loop.
If I wrap readline's rl_bind_key_in_map with a c function, then I can call it
but it's cumbersome.
#include <readline/keymaps.h>
#include <readline/readline.h>
extern int rl_bind_meta_key (int key, rl_command_func_t *func)
{
return rl_bind_key_in_map (key, func, emacs_meta_keymap);
}
(cffi:defcfun ("rl_bind_meta_key" rl_bind_meta_key) :int
(arg0 :int)
(arg1 :pointer))
CL-USER > (rl_bind_meta_key (char-code #\,)
(cffi:callback rl-magic-tab))
Below is a portion of the cffi readline binding
;;SWIG example
(in-package :rl)
(cffi:defcfun ("rl_initialize" rl_initialize) :int)
(cffi:defcfun ("readline" readline) :string
(arg0 :string))
(cffi:defcfun ("rl_insert" rl_insert) :int
(arg0 :int)
(arg1 :int))
;; extern int rl_bind_key PARAMS((int, rl_command_func_t *));
(cffi:defcfun ("rl_bind_key" rl_bind_key) :int
(arg0 :int)
(arg1 :pointer))
;; extern KEYMAP_ENTRY_ARRAY emacs_standard_keymap, emacs_meta_keymap,
emacs_ctlx_keymap;
(cffi:defcvar ("emacs_meta_keymap" emacs_meta_keymap)
:pointer)
;; extern int rl_bind_key_in_map PARAMS((int, rl_command_func_t *, Keymap));
(cffi:defcfun ("rl_bind_key_in_map" rl_bind_key_in_map) :int
(arg0 :int)
(arg1 :pointer)
(arg2 :pointer))
Thanks
fungsin