Vala: TypeModuleSample(CrossCompilation) and TypeModule/ added.
This commit is contained in:
parent
c5cef9fe2b
commit
52e1edf910
|
@ -0,0 +1,55 @@
|
||||||
|
class MyModule : TypeModule
|
||||||
|
{
|
||||||
|
[CCode (has_target = false)]
|
||||||
|
private delegate Type PluginInitFunc (TypeModule module);
|
||||||
|
|
||||||
|
private GLib.Module module = null;
|
||||||
|
|
||||||
|
private string name = null;
|
||||||
|
|
||||||
|
public MyModule (string name) {
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override bool load () {
|
||||||
|
string path = Module.build_path (Environment.get_variable ("PWD"), name);
|
||||||
|
module = Module.open (path, GLib.ModuleFlags.BIND_LAZY);
|
||||||
|
if (null == module) {
|
||||||
|
error ("Module not found");
|
||||||
|
}
|
||||||
|
|
||||||
|
void * plugin_init = null;
|
||||||
|
if (! module.symbol ("plugin_init", out plugin_init)) {
|
||||||
|
error ("No such symbol");
|
||||||
|
}
|
||||||
|
|
||||||
|
((PluginInitFunc) plugin_init) (this);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void unload () {
|
||||||
|
if (module != null)
|
||||||
|
message ("Library unloaded");
|
||||||
|
module = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Never unref instance of GTypeModule
|
||||||
|
// http://www.lanedo.com/~mitch/module-system-talk-guadec-2006/Module-System-Talk-Guadec-2006.pdf
|
||||||
|
static TypeModule module = null;
|
||||||
|
|
||||||
|
int main ()
|
||||||
|
{
|
||||||
|
module = new MyModule ("plugin");
|
||||||
|
module.load ();
|
||||||
|
|
||||||
|
var o = GLib.Object.new (Type.from_name ("MyClass"));
|
||||||
|
|
||||||
|
// free last instance, plugin unload
|
||||||
|
o = null;
|
||||||
|
|
||||||
|
module.unload ();
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
|
@ -0,0 +1,14 @@
|
||||||
|
public class MyClass : Object {
|
||||||
|
construct {
|
||||||
|
message("MyClass init");
|
||||||
|
}
|
||||||
|
|
||||||
|
~MyClass() {
|
||||||
|
message("MyClass deinit");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[ModuleInit]
|
||||||
|
Type plugin_init(GLib.TypeModule type_module) {
|
||||||
|
return typeof(MyClass);
|
||||||
|
}
|
|
@ -0,0 +1,15 @@
|
||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
# Cross-Platform: Works for GNU/Linux and Windows
|
||||||
|
|
||||||
|
valac -o loader loader.vala --pkg=gmodule-2.0
|
||||||
|
valac --ccode plugin.vala
|
||||||
|
if [[ `uname` == Linux ]]; then
|
||||||
|
libext=so
|
||||||
|
exeext=
|
||||||
|
else
|
||||||
|
libext=dll
|
||||||
|
exeext=.exe
|
||||||
|
fi
|
||||||
|
gcc -fPIC -shared -o libplugin.$libext plugin.c $(pkg-config --libs --cflags gobject-2.0 gmodule-2.0)
|
||||||
|
./loader$exeext
|
|
@ -0,0 +1,45 @@
|
||||||
|
public class PluginRegistrar<T> : Object {
|
||||||
|
|
||||||
|
public string path { get; private set; }
|
||||||
|
|
||||||
|
private Type type;
|
||||||
|
private Module module;
|
||||||
|
|
||||||
|
private delegate Type RegisterPluginFunction (Module module);
|
||||||
|
|
||||||
|
public PluginRegistrar (string name) {
|
||||||
|
assert (Module.supported ());
|
||||||
|
this.path = Module.build_path (Environment.get_variable ("PWD"), name);
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool load () {
|
||||||
|
stdout.printf ("Loading plugin with path: '%s'\n", path);
|
||||||
|
|
||||||
|
module = Module.open (path, ModuleFlags.BIND_LAZY);
|
||||||
|
if (module == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
stdout.printf ("Loaded module: '%s'\n", module.name ());
|
||||||
|
|
||||||
|
void* function;
|
||||||
|
module.symbol ("register_plugin", out function);
|
||||||
|
unowned RegisterPluginFunction register_plugin = (RegisterPluginFunction) function;
|
||||||
|
|
||||||
|
type = register_plugin (module);
|
||||||
|
stdout.printf ("Plugin type: %s\n\n", type.name ());
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public T new_object () {
|
||||||
|
return Object.new (type);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void main () {
|
||||||
|
var registrar = new PluginRegistrar<TestPlugin> ("plugin");
|
||||||
|
registrar.load ();
|
||||||
|
|
||||||
|
var plugin = registrar.new_object ();
|
||||||
|
plugin.hello ();
|
||||||
|
}
|
|
@ -0,0 +1,3 @@
|
||||||
|
public interface TestPlugin : Object {
|
||||||
|
public abstract void hello ();
|
||||||
|
}
|
|
@ -0,0 +1,11 @@
|
||||||
|
class MyPlugin : Object, TestPlugin {
|
||||||
|
public void hello () {
|
||||||
|
stdout.printf ("Hello world!\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public Type register_plugin (Module module) {
|
||||||
|
// types are registered automatically
|
||||||
|
return typeof (MyPlugin);
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,21 @@
|
||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
# Works under Linux only, not cross-platform
|
||||||
|
|
||||||
|
valac --pkg gmodule-2.0 main.vala plugin-interface.vala -o main
|
||||||
|
if [[ `uname` == Linux ]]; then
|
||||||
|
libext=so
|
||||||
|
exeext=
|
||||||
|
else
|
||||||
|
libext=dll
|
||||||
|
exeext=.exe
|
||||||
|
fi
|
||||||
|
valac --pkg gmodule-2.0 -C plugin.vala plugin-interface.vala
|
||||||
|
if [[ `uname` == Linux ]]; then
|
||||||
|
gcc -shared -fPIC $(pkg-config --cflags --libs glib-2.0 gmodule-2.0) \
|
||||||
|
-o libplugin.$libext plugin.c
|
||||||
|
else
|
||||||
|
gcc -shared -fPIC $(pkg-config --cflags --libs glib-2.0 gmodule-2.0 gobject-2.0) \
|
||||||
|
-o libplugin.$libext plugin.c $(pkg-config --libs glib-2.0 gmodule-2.0 gobject-2.0)
|
||||||
|
fi
|
||||||
|
./main$exeext
|
Loading…
Reference in New Issue