This example shows how to use modules (plugins) within your program and how to write such modules (plugins) with Vala.
The first thing needed is a common interface that will describe the interface between the main program and other modules / plugins.
Interface (plugin-interface.vala):
public interface TestPlugin : Object {
public abstract void hello ();
}
This should be put into its own file that is then shared between the main program and plugins.
Main program (main.vala):
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 ();
}
PluginRegistrar is a tool class that wraps registering, loading and creating new instances of TestPlugin class which are implemented in other classes contained in other modules.
Compiling:
$ valac --pkg gmodule-2.0 main.vala plugin-interface.vala -o main
A module must provide its own implementation of TestPlugin and a register_plugin method which is used to register the class in the main program.
Example of a plugin (plugin.vala):
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);
}
Compiling:
$ valac --pkg gmodule-2.0 -C plugin.vala plugin-interface.vala $ gcc -shared -fPIC $(pkg-config --cflags --libs glib-2.0 gmodule-2.0) -o libplugin.so plugin.c
Real World Example(s)
A real world Vala application that uses this code as the base for its plugin loading is Rygel.