エンジニアなプログラマ

プログラミング(特にvala言語関連)の話題を取り上げていきます。

現在、新しいクラス図描画ソフトを開発中! http://gridraw.com/

GLib.Test.add_func()でデリゲートを生成できないとき

目的

テストでGLib.Testを使用した際、add_func()の引数に関して次のようなコンパイルエラーが発生した。

Cannot create delegate without target for instance method or closure

この解決方法を検討する。

現象

例えば次のようなソース。

private class UnitTest {
    public void test_func() {
        print("test_func\n");
    }
}

static int main(string[] args) {
    Test.init(ref args);

    var ut = new UnitTest();
    Test.add_func("/test", () => { ut.test_func(); });

    return Test.run();
}

このソースだと、Test.add_funcの第2引数に関して、 冒頭のエラーが発生する。

原因

このエラーについて調べると、下記stackoverflowのスレッドにたどり着いた。

http://stackoverflow.com/questions/11314163/what-does-cannot-create-delegate-without-target-for-instance-method-or-closure-m

どうやら、[CCode (has_target = false)]が付与されているデリゲートに対して、 クロージャインスタンスを使用するデリゲートは渡せないようだ。

ドキュメントを参照すると、Test.add_funcの第2引数はTestFunc型となっている。 この宣言は、

[ CCode ( has_target = false ) ]
public delegate void TestFunc () 

となっており、確かに[CCode (has_target = false)]が付与されている。

解決方法

Test.add_funcの代わりにTest.add_data_funcを使用する。

Test.add_data_funcの第2引数はTestDataFunc型となっている。 この宣言は、

public delegate void TestDataFunc () 

となっており、TestFuncから[CCode (has_target = false)]を除いたデリゲートとなっている。

上記ソースのTest.add_funcTest.add_data_funcに置き換えれば、本エラーは解決する。