[cffi-devel] How to pass foreign pointer to c function
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
On 30/11/2007, fungsin <fungsin.lui@gmail.com> wrote:
return rl_bind_key_in_map (key, func, emacs_meta_keymap);
AFAICT, emacs_meta_keymap is an array. My C-fu is getting weak but I think that in this particular case emacs_meta_keymap (or &emacs_meta_keymap[0]) == &emacs_meta_keymap.
(cffi:defcvar ("emacs_meta_keymap" emacs_meta_keymap) :pointer)
So, given that definition, the equivalent of &emacs_meta_keymap is (get-var-pointer 'emacs_meta_keymap). Alternatively, you can use (foreign-symbol-pointer "emacs_meta_keymap"). -- Luís Oliveira http://student.dei.uc.pt/~lmoliv/
participants (2)
-
fungsin
-
Luís Oliveira