有没有一种方法可以从gobject内省中注册类型?

时间:2020-05-06 10:15:50

标签: glib vala gobject

我目前正在尝试使用gobject-introspection库。我想做的一件事就是能够从我所获得的信息中注册类型(尤其是类)。具体来说,我可以获得一个GLib.Type,然后可以用它来实例化一个GLib.Object.new

我已经从typelib成功加载了名称空间,并且可以获取有关名称空间中的类等的信息,但是我不确定如何从那里继续前进?

static void main(string[] args){

    var rep = GI.Repository.get_default();
    rep.require("Gtk", null, 0);

    var oinfo = (GI.ObjectInfo)rep.find_by_name("Gtk", "Button");

}

oinfo中,我现在可以轻松地获取类的名称,等等,据我所知,我在那里拥有所有元数据。但是,假设我不能引用类似typeof(Gtk.Button)的类型,或者直接在代码中引用它,如何在类型系统中注册该类型以便实例化?

1 个答案:

答案 0 :(得分:0)

是的,经过一番修补后,我自己解决了这个问题。但毕竟事实并非如此困难。最复杂的方法是使用刚刚编译的共享库,因此我的示例将涉及到这一点:

首先,让我们创建一个在一个文件中仅包含一个类的共享库:

namespace TestLib{

    public class TestBase : Object{

        private static int counter = 0;

        public int count{
            get{
                return ++counter;
            }
        }

    }

}

这需要编译为共享库文件 valac --library=TestLib -H TestLib-1.0.h --gir=TestLib-1.0.gir TestLib.vala -X -fPIC -X -shared -o TestLib.so 然后使用gir编译器并生成typelib g-ir-compiler --shared-library=TestLib TestLib-1.0.gir -o TestLib-1.0.typelib

然后我们编写要运行的程序:

using GI;

namespace TestRunner{

    static int main(string[] args){

        var namesp = "TestLib"; //set the name of the namespace we want to load
        var rep = Repository.get_default(); //Obtain default repository

        rep.require_private(".", namesp, null, 0); //load namespace info from the current folder (this assumes the typelib is here)

        var rtinfo = (RegisteredTypeInfo)rep.find_by_name(namesp, "TestBase"); //retrieves the BaseInfo of any type in the "TestLib" namespace called "TestBase" and casts it

        var type = rtinfo.get_g_type(); //Calls the get type, registrering the type with the type system, so now it can be used as we wish

        var objt = Object.new(type); //object is instantiated, and we can use it

        Value val = Value(typeof(int));
        objt.get_property("count", ref val);

        message(val.get_int().to_string());

        objt.get_property("count", ref val);

        message(val.get_int().to_string());

        message("type is: %s".printf(type.name()));

        return 0;

    }

}

然后我们编译该程序:valac TestLib.vapi TestRunner.vala -X TestLib.so -X -I. -o testintro --pkg=gobject-introspection-1.0 在运行它之前,我们将记住将该目录添加到路径中,以便程序知道在哪里可以找到共享库:export LD_LIBRARY_PATH=.

最后,我们运行新程序:./testintro

我们应该看到:

** Message: 22:45:18.556: TestRunner.vala:9: Chosen namespace is: TestLib
** Message: 22:45:18.556: TestRunner.vala:24: 1
** Message: 22:45:18.556: TestRunner.vala:28: 2
** Message: 22:45:18.556: TestRunner.vala:30: type is: TestLibTestBase
相关问题