[Vala] struct value boxing in GLib.Array



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



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