Vala: TypeModuleSample(CrossCompilation) and TypeModule/ added.

This commit is contained in:
Kolan Sh 2014-09-12 16:37:42 +04:00
parent c5cef9fe2b
commit 52e1edf910
7 changed files with 164 additions and 0 deletions

View File

@ -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;
}

View File

@ -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);
}

15
vala/TypeModuleSample/run.sh Executable file
View File

@ -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

View File

@ -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 ();
}

View File

@ -0,0 +1,3 @@
public interface TestPlugin : Object {
public abstract void hello ();
}

View File

@ -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);
}

21
vala/TypeModules/run.sh Executable file
View File

@ -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