GLib 関数で得た gchar** つまり文字列の配列の要素数。
ってよく考えたら Vala は foreach できるじゃないか。
/* valac -C test.vala */ class Test { public static int main(string[] args) { var l = Environment.list_variables(); foreach (var s in l) { stdout.printf("%s\n", s); } return 0; } }
g_get_environ のバインドが何故か無いので g_getenv バインドで。
コレがビルドできるということは Vala は要素数を得ているということ。
ということで毎度のように -C オプションしてチェック。
gint get_array_length (gchar** array) { gint length = 0; if (array) while (array[length]) length++; return length; }
これだけ?
配列がメモリ上でどうなっているか知っていれば確かに納得だけーが。
(char**) つかヒープ領域つか動的配列専用になってしまうな。
(char[ ][ ]) のスタック変数には絶対に使ってはいけない。
コッチはゴロゴロ見付かる方法で、と使い分けてください。
(char**) (char[ ][ ]) の両対応ははたして可能なのか?
とにかくテストコードを書いて確認。
#include <glib.h> gint get_array_length (gchar** array) { gint length = 0; if (array) while (array[length]) length++; return length; } gchar** create_array(void) { gchar** arg; arg = (gchar**)g_malloc0(sizeof(gchar*) * 4); arg[0] = g_strdup("YAMAHA"); arg[1] = g_strdup("HONDA"); arg[2] = g_strdup("KAWASAKI"); arg[3] = g_strdup("SUZUKI"); return arg; } int main (int argc, char *argv[]) { gchar** array; gint i, count; array = create_array(); count = get_array_length(array); g_printf("count=%d\n", count); for (i=0; i<count; i++) { g_printf("%s\n", array[i]); } g_strfreev(array); return 0; }
上記は g_malloc0 でゼロ詰めしてセグメントエラーは一応回避している。
でも実際にアプリに使うとなると少し不安な感じ。
arg[2] = NULL;
等には完全に無力なわけで。
でもそれは配列を作る側の問題。
確実にいえるのは GLib 関数の戻り値に使うかぎりはコレで問題ない。
自前動的配列に使う場合はチョッピリ注意しよう。