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 <[email protected]>

_______________________________________________
Vala-list mailing list
[email protected]
http://mail.gnome.org/mailman/listinfo/vala-list

Reply via email to