我目前正在尝试使用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)
的类型,或者直接在代码中引用它,如何在类型系统中注册该类型以便实例化?
答案 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