GNOME Bugzilla – Bug 623254
vapigen creates struct instead of a [Compact] class from a compact C class
Last modified: 2010-07-08 20:34:26 UTC
Created attachment 165003 [details] The source .gir segment In my hand-created Vala bindings for telepathy-glib, the TpIntSet "compact class" is labeled as a <boxed> type, and ends up as a [Compact] class in the final .vapi file. It's basically a full class except that the _TpIntSet struct is opaque. The same C code parsed through g-ir-scanner and then vapigen ends up being a struct, which valac doesn't seem to handle well. It ends up generating lines like: TpIntSet foo = {0}; which of course fail, since gcc doesn't know how large TpIntSet is. I'll attach the .gir segment, the expected and actual .vapi segments. You may want to refer to telepathy-glib's telepathy-glib/telepathy-glib/intset.[ch] for the original code. This bug blocks fdo bug #27792.
Created attachment 165004 [details] The actual generated .vapi segment
Created attachment 165005 [details] The expected .vapi segment
It look to me as if the .gir file is missing some information here. We could infer that the struct is heap-allocated by the lack of fields (although that will break for not completely opaque heap-allocated structs). However, vapigen still couldn't know that tp_int_set_destroy needs to be called to free the struct. Any insights on this issue?
Adding bug #623635 as a see-also. We'll re-implement the existing heuristic in vapigen and close this bug, but we can simplify it once bug #623635 is closed.
FWIW, PyGObject uses the GType API to infer that this struct is a boxed and to access the _copy and _free functions. It uses the g-i API to get the size of the struct and allocates it in the heap with g_slice_malloc0(), but maybe it should try to find first a constructor with no parameters (such as tp_intset_new).
After a bit of discussion in #introspection, we learned: * any boxed type with a public get_type function should appear as a <record> with a glib:get-type attribute listing its get_type function. This can be called to determine whether it's a descendant of GBoxed (in which case its copy/free functions are just g_boxed_copy/g_boxed_free) * glib:boxed is just entities where we don't know if they're structs or unions. But we may know their get_type function, so we may be able to determine their copy/free functions based on that So the priority is in using the glib:get-type value to determine whether the entity is a descendant of GBoxed.
commit f4ee97b1b2d99915bff8c209c04731ed9dc53866 Author: Jürg Billeter <j@bitron.ch> Date: Thu Jul 8 21:16:04 2010 +0200 girparser: Fix support for boxed types Fixes bug 623254.