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