Hi,

that's what I was affraid of - unfortunately the actual library I was talking 
about uses GArray this way in a lot of places, and to make things worse it is 
usually found as a value of a GHastTable.. anyway - I see no other way than to 
write helper function which would return normal array, as you've suggested. 
Something like:

void *array_from_garray(GArray *array, gsize *ret_size)
{
  *ret_size = array->len;
  return array->data;
}

which makes me wonder - the "data" field should be public, therefore I should 
be able to acces them inside Vala if I add the "data" field to the glib VAPI, 
right? But I'm affraid that's not something most people would want to see there 
:(

Anyway, thanks for help!

Regards,
Jan Spurny

>  ------------ Původní zpráva ------------
>  Od: Michael Brown <[email protected]>
>  Předmět: Re: [Vala] struct value boxing in GLib.Array
>  Datum: 21.7.2011 11:54:50
>  ----------------------------------------
>  I can't find a way to do what you want. Generics in vala is based on the
>  idea that the type should fit into a 32 bit pointer, so int32 ok, int64 not
>  ok. Hence the requirement to box some types. Unfortunately this just doesn't
>  work too well with something like GLib.Array. The second nail in the coffin,
>  so to speak, is that struct returns in vala are done via a pointer passed
>  into the method. g_array_index returns an l-value of the actual array entry.
>  Nice for C code, but not for codegen.
>  
>  Is it possible for you to use a vanilla array, such as Point[]  ?
>  
>  
>  On 21 July 2011 02:21, Jan Spurny <[email protected]> wrote:
>  
>  > Hi,
>  >
>  > I have some trouble with using one C library which is using value-copied
>  > structs inside GLib.Array container. Here is a small piece of code to
>  > illustrate the problem:
>  >
>  > x.c
>  > --------------------------------------
>  > #include "x.h"
>  > GArray* get_array() {
>  >   GArray *result = g_array_new(FALSE, FALSE, sizeof(Point));
>  >   Point a = { 1, 2 };
>  >   Point b = { 3, 5 };
>  >   g_array_append_val(result, a);
>  >   g_array_append_val(result, b);
>  >   return result;
>  > }
>  > --------------------------------------
>  >
>  > x.h:
>  > --------------------------------------
>  > #include <glib.h>
>  > typedef struct Point_ Point;
>  > struct Point_ {
>  >  int x;
>  >  int y;
>  > };
>  > GArray* get_array();
>  > --------------------------------------
>  >
>  > x.vapi:
>  > --------------------------------------
>  > [SimpleType]
>  > [CCode (cheader_filename = "x.h")]
>  > public struct Point {
>  >  public int x;
>  >  public int y;
>  > }
>  >
>  > [CCode (cheader_filename = "x.h")]
>  > public GLib.Array<Point> get_array();
>  > --------------------------------------
>  >
>  > pgm.vala:
>  > --------------------------------------
>  > void main (string[] args)
>  > {
>  >    var pts = get_array();
>  >    for (int i = 0 ; i < pts.length; i++) {
>  >        var p = pts.index(i);
>  >        stdout.printf(@"pt: $(p.x), $(p.y)\n");
>  >    }
>  > }
>  > --------------------------------------
>  >
>  > (compile: "valac -X -I. --vapidir=. --pkg glib-2.0 --pkg x -o pgm pgm.vala
>  > x.c")
>  >
>  > Now it DOES NOT COMPILE:
>  >  x.vapi:9.19-9.23: error: `Point' is not a supported generic type argument,
>  > use `?' to box value types
>  >  public GLib.Array<Point> get_array();
>  >                    ^^^^^
>  > But when I change the line in VAPI file to "public GLib.Array<Point?>
>  > get_array();" it DOES COMPILE, but it doesn't work.
>  > The resulting binary segfaults when executed because the generated C file
>  > "thinks" the type in the GLib.Array is "Point*", but it is in fact "Point" 
> -
>  > see the generated C code:
>  >
>  > ---------------------------------------
>  > void _vala_main (gchar** args, int args_length1) {
>  >        GArray* _tmp0_ = NULL;
>  >        GArray* pts;
>  >        _tmp0_ = get_array ();
>  >        pts = _tmp0_;
>  >        {
>  >                gint i;
>  >                i = 0;
>  >                {
>  >                        gboolean _tmp1_;
>  >                        _tmp1_ = TRUE;
>  >                        while (TRUE) {
>  >                                Point* _tmp2_ = NULL;
>  >                                Point* _tmp3_;
>  >                                Point* p;
>  >                                ...
>  >                                _tmp2_ = g_array_index (pts, Point*, (guint)
>  > i);
>  >                                _tmp3_ = __point_dup0 (_tmp2_);
>  >                                p = _tmp3_;
>  >                                ....
>  > ---------------------------------------
>  >
>  >
>  > I would very much prefer to keep the C library (the example above is only
>  > an example, the real C library is quite large) and solve the problem on the
>  > "vala side".. does anyone have any suggestions?
>  >
>  > Thanks for any help.
>  >
>  >
>  > Regards,
>  > Jan Spurny
>  > _______________________________________________
>  > vala-list mailing list
>  > [email protected]
>  > http://mail.gnome.org/mailman/listinfo/vala-list
>  >
>  
>  
>  
>  -- 
>  Michael Brown
>  
>  
>  
_______________________________________________
vala-list mailing list
[email protected]
http://mail.gnome.org/mailman/listinfo/vala-list

Reply via email to