有没有办法从gobject自省中注册类型?

问题描述 投票:1回答:1

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

我已经成功地从tyelib中加载了一个命名空间,我可以得到命名空间中的类等信息,但我不确定如何从那里继续前进?

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) 或在代码中直接引用它, 我如何在类型系统中注册这个类型,以便我可以实例化它?

glib vala gobject
1个回答
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 编译器并生成 typelibg-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在运行之前,我们要记得在路径中添加这个dir,这样程序就知道在哪里可以找到共享库。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
© www.soinside.com 2019 - 2024. All rights reserved.