LINUX.ORG.RU

[Lisp & GTK3] Не работает FFI в SBCL & CMUCL


0

1

Вот минимальный кусок кода

(asdf:oos 'asdf:load-op :cffi)
(in-package :cffi)

(load-foreign-library "/usr/lib/libgtk-3.so.0.0.11")

(foreign-funcall "gtk_init" :int 0 :pointer (foreign-alloc :string :initial-element "program") :void)

(defvar *window*)

(setq *window* (foreign-funcall "gtk_window_new" :int 0 :pointer))

(foreign-funcall "g_signal_connect_data" :pointer *window* :string "destroy" :pointer (foreign-symbol-pointer "gtk_main_quit") :pointer (null-pointer)  :pointer (null-pointer) :int 0 :void)

(foreign-funcall "gtk_widget_show" :pointer *window* :void)

(foreign-funcall "gtk_main" :void)

После запуска отрисовывается окно, но при наведении на него мышки, вылетает с ошибкой деления на 0. В clisp и ccl всё работает без ошибок. В GTK-2 — тоже.

Кто-нибудь может помочь или посоветовать куда копать (пробовал блокировать обработчики motion_notify_event, enter_notify_event, focus_in_event, proximity_in_event — не помогло: разве что запускаются они непосредственно перед тем самым делением на ноль)

★★★★★

У вас неверные сигнатуры функций. Например, g_signal_connect_data. gtk_init принимает указатель на целое + указателей на массив строк (строка = указатель на начало строки), у вас же передается целое + указатель на одну строку. g_signal_connect_data возвращает не void, а ulong (для cffi это тип :unsigned-long).

Это то, что сразу бросается в глаза.

dmitry_vk ★★★
()
Ответ на: комментарий от anonymous

Is it Irish/welsh/scotish? Sorry can't understand your dialect

anonymous
()
Ответ на: комментарий от anonymous

> I got it. What has your speech defect have to do with CL?

My classic tongue (though, feel free to call it «a defect», it's so pretty natural for the illiterate) has nothing to do with Common Lisp.

Your arse-hurt - has to.

anonymous
()
Ответ на: комментарий от dmitry_vk

у вас же передается целое + указатель на одну строку

А здесь написано, что

;;; Allocate a char** pointer that points to newly allocated memory
;;; by the :string type translator for the string "foo".
CFFI> (foreign-alloc :string :initial-element "foo")

возвращает не void, а ulong

Возвращаемые значения по стандарту C можно игнорировать. Если я вместо int main напишу void main ничего плохого не происходит.

А по существу: можешь в SBCL сделать на GTK3 окно и поводить по нему мышкой, чтобы GTK при этом не упал?

monk ★★★★★
() автор топика
Ответ на: комментарий от monk

> А по существу: можешь в SBCL сделать на GTK3 окно и поводить по нему мышкой, чтобы GTK при этом не упал?

Ты ничего не понимаешь, Common Lisp работает по-другому.

anonymous
()
Ответ на: комментарий от monk

>Возвращаемые значения по стандарту C можно игнорировать.

Это зависит от ABI и от реализации FFI. Я вот навскидку не смогу сказать, как в SBCL передаются возвращаемые значения. В любом случае, хуже от правильной сигнатуры точно не будет. Но и в том, что причина падения в этом, я не уверен.

Если я вместо int main напишу void main ничего плохого не происходит

Функция main обрабатывается компилятором C особым образом.

А здесь написано, что

Да, действительно. Но в любом случае, у вас передается char**, а должен char***. Т.е., нужно передавать (foreign-alloc :pointer :initial-element (foreign-alloc :string :initial-element «program»)).

dmitry_vk ★★★
()

После запуска отрисовывается окно, но при наведении на него мышки, вылетает с ошибкой деления на 0.

А, я вспомнил, в чем тут дело. SBCL по умолчанию включает FPU Exceptions, а Gtk+ где-то делается деление на ноль и подобные операции, возвращающие Inf, NaN. Поэтому надо сделать вот так:

 (sb-ext::set-floating-point-modes :traps nil) 
dmitry_vk ★★★
()
Ответ на: комментарий от dmitry_vk

Ура! Заработало!

Спасибо за совет. Ещё бы ссылку, что почитать по SBCL (google на поиск по «set-floating-point-modes site:sbcl.org» выдает какую-то муть.

Насчет char*** — тоже проглядел. увидел argv — тип на автомате проставил.

monk ★★★★★
() автор топика

Глобаольно. Надёжно. Choose Common Lisp.

anonymous
()
Ответ на: комментарий от dmitry_vk

> Gtk+ где-то делается деление на ноль и подобные операции, возвращающие Inf, NaN

Круто.

dave ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.