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