Recentlly I’ve tried to write a small Hello World
program using ctypes
and gtk4
. My problem is g_object_unref
which is called when the application has already run fails with SIGSEGV (Address boundary error)
I run the program (on Fedora 36) with ocaml hello.ml
and here is the program:
#use "topfind";;
#thread;;
#require "ctypes";;
#require "ctypes.foreign";;
open Ctypes;;
open Foreign;;
let gtk4 = Dl.dlopen ~flags:Dl.[RTLD_NOW] ~filename:"libgtk-4.so";;
let gtk4 = foreign ~from:gtk4;;
let gio = Dl.dlopen ~flags:Dl.[RTLD_NOW] ~filename:"libgio-2.0.so";;
let gio = foreign ~from:gio;;
let gobject = Dl.dlopen ~flags:Dl.[RTLD_NOW] ~filename:"libgobject-2.0.so";;
let gobject = foreign ~from:gobject;;
type window = unit ptr;;
type application = unit ptr;;
type widget = unit ptr;;
let window : window typ = ptr void;;
let application : application typ = ptr void;;
let widget : widget typ = ptr void;;
type gpointer = unit ptr;;
let gpointer : gpointer typ = ptr void;;
let callback_t = application @-> gpointer @-> returning void;;
let application_new =
gtk4 "gtk_application_new" (string @-> int @-> returning application);;
let application_window_new =
gtk4 "gtk_application_window_new" (application @-> returning window);;
let window_set_title =
gtk4 "gtk_window_set_title" (window @-> string @-> returning void);;
let window_set_default_size =
gtk4 "gtk_window_set_default_size" (window @-> int @-> int @-> returning void);;
let widget_show =
gtk4 "gtk_widget_show" (widget @-> returning void);;
let application_run =
gio "g_application_run" (application @-> int @-> gpointer @-> returning int);;
let application_run app = application_run app 0 null;;
let object_unref =
gobject "g_object_unref" (ptr void @-> returning void);;
let signal_connect =
gobject "g_signal_connect_data" (application @-> string @-> funptr callback_t @-> gpointer @-> returning void);;
let activate : application -> gpointer -> unit =
fun app data ->
let win = application_window_new app in
window_set_title win "Hello Ctypes";
window_set_default_size win 200 200;
widget_show win
;;
let main () =
let app = application_new "org.example.hello" 0 in
signal_connect app "activate" activate null;
let status = application_run app in
object_unref app;
print_endline @@ string_of_int status
;;
main ();;
I can guess why this may happen, but no idea how to fix it.