Hello,
I'm writing a binding to Agar (http://libagar.com), an SDL GUI library (among other things), but I'm facing a problem:
AG_Editable objects can be bound to a text buffer so the text entered into the editable widget is written into that buffer and vice versa. The buffer can be set with void AG_EditableSetString(AG_Editable *ed, char *text);
The following C Program works fine:
#include <agar/core.h> #include <agar/gui.h> int main(int argc, char **argv) { AG_InitCore("myprog", 0); AG_InitVideo(320, 240, 32, 0); char buffer[100]; /* text buffer */ AG_Window *win = AG_WindowNew(0); AG_Textbox *tb = AG_TextboxNew(win, 0, "testbox:"); AG_Editable *ed = tb->ed; AG_WindowShow(win); AG_EditableBindUTF8(ed, &buffer, 100); /* no hang here */ AG_EditableSetString(ed, "foobar"); AG_EventLoop(); return 0; }
Whereas the following CFFI Lisp, which is supposed to be equivalent, at the REPL does not:
(with-core-and-video (cffi:with-foreign-object (buffer :char 100) (let* ((win (cffi::foreign-funcall "AG_WindowNew" :int 0 :pointer)) (tb (cffi::foreign-funcall "AG_TextboxNew" :pointer win :int 0 :string "box:" :pointer)) (ed (cffi::foreign-slot-value tb 'ag-cffi::textbox 'ag-cffi::editable))) (ag:window-show win) ;; hangs here: (cffi::foreign-funcall "AG_EditableBindUTF8" :pointer ed :pointer buffer :int 100 :void) (cffi::foreign-funcall "AG_EditableSetString" :pointer ed :string "foobar" :void) (cffi::foreign-funcall "AG_EventLoop_FixedFPS" :void))))
The program hangs at the line with the according comment. The window shows up but doesn't get into the event loop, there are no error conditions and if I interrupt in Slime with C-c C-c (which works), the backtrace always reads "bogus stack frame" > "foreign function" > "foreign function" > (lambda ()) > (sb-int:simple-eval-in-lexenv ...) > ...
What could cause this and how do I fix it? Or did I do something wrong?
Best regards, Jakob
I found the problem. I was just grovelling this ag-cffi::editable slot with the wrong type (the struct type instead of :pointer).
Whereas the following CFFI Lisp, which is supposed to be equivalent, at the REPL does not:
(with-core-and-video (cffi:with-foreign-object (buffer :char 100) (let* ((win (cffi::foreign-funcall "AG_WindowNew" :int 0 :pointer)) (tb (cffi::foreign-funcall "AG_TextboxNew" :pointer win :int 0 :string "box:" :pointer)) (ed (cffi::foreign-slot-value tb 'ag-cffi::textbox 'ag-cffi::editable))) (ag:window-show win) ;; hangs here: (cffi::foreign-funcall "AG_EditableBindUTF8" :pointer ed :pointer buffer :int 100 :void) (cffi::foreign-funcall "AG_EditableSetString" :pointer ed :string "foobar" :void) (cffi::foreign-funcall "AG_EventLoop_FixedFPS" :void))))