GNOME Bugzilla – Bug 578421
SQLite: Invalid array lengths in callback
Last modified: 2009-11-24 08:58:27 UTC
Please describe the problem: The functions without length of array, use -1 instead of compute the real length of the array. Steps to reproduce: The minimum code to reproduce the problem: void print_array ([CCode (array_length = false)] string[] arr) { foreach (string s in arr) { print ("%s\n", s); } } void main (string[] args) { string[] arr = {"1", "2"}; print_array (arr); } Actual results: In the generated C code, the length of array is -1: for (s_it = 0; s_it < -1; s_it = s_it + 1) { Expected results: Does this happen every time? yes Other information: When copying an array, this produces a segfault: _vala_array_dup1 (_tmp1, -1)
The array_length attribute should only be used in bindings, never in Vala code. Can you explain why this is an issue?
I have added the array_length attribute for try to resolve the problem. The copy of the arrays seems ok. But the original code doesn't work: using Sqlite; class Dba { Database db; int rc; public string[] db_result; public Dba() { rc = Database.open ("list.db", out db); } public string[] get_all_list () { string sql = "SELECT * FROM list"; db.exec (sql, select_callback); db = null; return db_result; } [Callback] private int select_callback (int n_columns, string[] values, string[] column_names) { db_result = values; return 0; } } In the generated C code, the callback function pass -1 for the length of the array: static gint _dba_select_callback_sqlite3_callback (gpointer self, gint n_columns, char** values, char** column_names) { return dba_select_callback (self, n_columns, values, -1, column_names, -1); }
The SQLite API is a bit funky in places, which means the vala bindings are a bit akward, too. The problem here is that the callback function in sqlite takes void*,int,char**,char**. The first parameter is taken up with the object (this in vala, self in the generated C). The next parameter is actually the length of both of the next *two* arrays of strings. This is unusual--it would generally be one length parameter per array. Vala doesn't support handling this automatically, so the sqlite bindings mark both arrays as not having a length parameter, and let you deal with the length (n_columns) yourself. A -1 length in vala basically means that the true length is unknown (usually that translates to a null terminated array, but not in this case). Try inserting "values.length = column_names.length = n_columns;" at the beginning of your callback function. After that, the length property should be what you would expect. An argument could be made that the n_columns should be treated as the length of values, but column_names would still be -1. I prefer consistency, though, so I would leave it as is.