Re: [Vala] Variable sized structs and vapi files



Hello,

On Tue, September 15, 2009 00:09, Jan-Jaap van der Geer wrote:
I wonder how to "vapify" a struct that has a variable part at the
end, such as the wimp_menu below (somewhat simplyfied):

struct wimp_menu_entry
   {  wimp_menu_flags menu_flags;
      wimp_menu *sub_menu;
   };

#define wimp_MENU_MEMBERS \
   int width; \
   int height;

struct wimp_menu
   {  wimp_MENU_MEMBERS
      wimp_menu_entry entries [UNKNOWN];
   };

UNKNOWN is defined to be 1, but the intended structure can be any
length, dependent on what is apropriate. It is actually recommended
to use a macro for defining the structure:

#define wimp_MENU(N) \
   struct \
      {  wimp_MENU_MEMBERS \
         wimp_menu_entry entries [N]; \
      }

I wonder how to do this. Somehow Vala needs to know how to allocate
and free the memory for these structures, so I suppose it somehow
needs to be told - but I do not know how.

Any ideas?

YUCK! Many objects in GLib are actually allocated with different size
than declared, but it is always hidden in allocator functions.

I see several options:

 1) Get the C API redefined to use:

    struct wimp_menu {
        int width;
        int height;
        wimp_menu_entry *entries;
    };

    This could easily be bound in vala as a struct and all expected
    operations would work on it, too (well, would also need a length
    there).

    In C, this has the disadvantage, that the entries array must be
    declared as a separate variable.

 2) Get a dynamic allocator into the API. It should look like:

    wimp_menu_entry_new(int n);

    or better

    wimp_menu_entry_new(int n, wimp_menu_entry[] entries);

    (where the entries will be copied to the allocated structure)
    Than you can bind the wimp_menu_entry as a [Compact] class and bind
    this method as it's constructor. If you get the later, you can bind
    it as

    [Compact]
    public class Menu {
        ...
        public Menu([CCode(array_length_pos = 0.9)] MenuEntry[] entries);
        ...

    A delete function does not need to be defined, because you can easily
    specify
    [CCode(free_function = "free")]
    (or g_free, depending on whether it will be allocated with malloc or
    g_malloc)
    on the class definition.

 3) Define the allocator function in a helper header in your project.
    It could be a macro like:

    #define wimp_menu_entry_new(int n) \
         g_malloc0(sizeof(wimp_menu) + \
                   (n - 1) * sizeof(wimp_menu_entry))

    The other definition would be more useful, because you wouldn't
    have to set the entries item-by-item, but also a bit more complicated.

Related: Is there documentation about this? If so where can I find
that?

Very scarce. Look through the wiki, but mostly you will have to
look how similar things are done in the existing .vapi files.

-- 
                                        - Jan Hudec <bulb ucw cz>




[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]