Re: [Vala] Fwd: Delegate with out parameters are not working within lambdas



Il giorno dom, 17/05/2009 alle 12.03 +0200, Mike Massonnet ha scritto:
Hi,

When using this code:

| ...

the lamdba function isn't working because instead of passing gint *x
it passes gint x. Here is the error message:


I guess this issue is still present, isn't it?

In fact, I was trying this code:

/***********************************************************************/
using GLib, Sqlite;

/* 
sqlite3 sqlite-test.db << EOF
CREATE TABLE mytable (id INTEGER, data TEXT);
INSERT INTO mytable VALUES (0, "First row");
INSERT INTO mytable VALUES (1, "Second row");
INSERT INTO mytable VALUES (2, "Third row");
EOF
*/

class SqliteTest : Object {
        private delegate bool SqliteStatementCb(ref Statement stmt);
        private Database db = null;

        public SqliteTest() {
                Database.open("/tmp/sqlite-test.db", out this.db);
        }
        
        private bool statement_init(out Statement stmt, string sql) {
                bool ret = this.db.prepare_v2(sql, -1, out stmt);
                return (ret == Sqlite.OK);
        }
        
        private bool statement_parse(ref Statement stmt,
                                SqliteStatementCb? func = null) {
                int ret = Sqlite.ERROR;
                stmt.reset();

                do {
                        ret = stmt.step();
                        switch (ret) {
                                case Sqlite.DONE:
                                break;
                        case Sqlite.ROW:
                                if (func != null) {
                                        if (!func(ref stmt))
                                                return false;
                                }
                                break;
                        default:
                                print("Statement error:%d, %s\n"
                                        .printf(ret, this.db.errmsg()));
                                return false;
                        }
                } while (ret == Sqlite.ROW);

                return true;
        }

        public bool test(string sql) {
                int[] ids = {};
                Statement stmt;
                statement_init(out stmt, sql);
                statement_parse(ref stmt, (s) => {
                        int id = s.column_int(0);
                        ids += id;
                        print("%d\n",id);
                        return true;
                });
                
                return (ids.length > 0);
        }
}

void main() {
        var sqlite = new SqliteTest();
        sqlite.test("SELECT * FROM mytable");
}

/***********************************************************************/

In this case the generated C code is wrong, in fact the lambda functions
is written as:

static gboolean _lambda0_ (sqlite3_stmt* s, Block1Data* _data1_) {
                         //^^ Wrong pointer, it should be sqlite3_stmt**
        SqliteTest * self;
        gboolean result = FALSE;
        gint _tmp0_;
        gint id;
        self = _data1_->self;
        g_return_val_if_fail (s != NULL, FALSE);
        _tmp0_ = sqlite3_column_int (s, 0);
        id = _tmp0_;
        _vala_array_add1 (&_data1_->ids, &_data1_->ids_length1,
&_data1_->_ids_size_, id);
        g_print ("%d\n", id);
        result = TRUE;
        _sqlite3_finalize0 (s); // Why should it be free'd?!?
        return result;
}

As you can see here there are two issues: 
 - Just a sqlite3_stmt* is passed to the function while it would have
   needed a sqlite3_stmt** (the passed sqlite3_stmt is already a
   pointer)
 - The passed poiunter is free'd at the end of the lambda function (via 
   _sqlite3_finalize0), while this operation shouldn't be performed for
   a lambda ref parameter (since the lambda doesn't own that var, why
   should it free?!)

In this specific situation, I can bypass the issue by just using a
lambda without parameter in a such way:

statement_parse(ref stmt, () => {
        int id = stmt.column_int(0);
        ids += id;
        print("%d\n",id);
        return true;
});

This work, but the bug rests. Should it be reported in another place?

Thanks.





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