The Module struct is an opaque data structure to represent a dynamically-loaded module.
It should only be accessed via the following functions.
Example: Loading modules (plugins):
// Shared library:
public errordomain PluginError {
NOT_SUPPORTED,
UNEXPECTED_TYPE,
NO_REGISTRATION_FUNCTION,
FAILED
}
public interface PluginIface : Object {
public abstract void registered (PluginLoader loader);
public abstract void activated ();
public abstract void deactivated ();
// get_desctiption (), get_name (), ...
}
private class PluginInfo : Object {
public Module module;
public Type gtype;
public PluginInfo (Type type, owned Module module) {
this.module = (owned) module;
this.gtype = type;
}
}
public class PluginLoader : Object {
[CCode (has_target = false)]
private delegate Type RegisterPluginFunction (Module module);
private PluginIface[] plugins = new PluginIface[0];
private PluginInfo[] infos = new PluginInfo[0];
public PluginIface load (string path) throws PluginError {
if (Module.supported () == false) {
throw new PluginError.NOT_SUPPORTED ("Plugins are not supported");
}
Module module = Module.open (path, ModuleFlags.BIND_LAZY);
if (module == null) {
throw new PluginError.FAILED (Module.error ());
}
void* function;
module.symbol ("register_plugin", out function);
if (function == null) {
throw new PluginError.NO_REGISTRATION_FUNCTION ("register_plugin () not found");
}
RegisterPluginFunction register_plugin = (RegisterPluginFunction) function;
Type type = register_plugin (module);
if (type.is_a (typeof (PluginIface)) == false) {
throw new PluginError.UNEXPECTED_TYPE ("Unexpected type");
}
PluginInfo info = new PluginInfo (type, (owned) module);
infos += info;
PluginIface plugin = (PluginIface) Object.new (type);
plugins += plugin;
plugin.registered (this);
return plugin;
}
// ...
}
valac -o libshared.so --pkg gmodule-2.0 --library libshared -H libshared.h -X -fPIC -X --shared library.vala
// The plugin:
private class MyPlugin : Object, PluginIface {
public void registered (PluginLoader loader) {
print ("Loaded\n");
}
public void activated () {
print ("Activate\n");
}
public void deactivated () {
print ("Deactivate");
}
}
public Type register_plugin (Module module) {
return typeof (MyPlugin);
}
valac -o libmyplugin.so --pkg gmodule-2.0 -X -fPIC -X --shared libshared.vapi myplugin.vala --library myplugin
// The programm:
public static int main (string[] args) {
if (args.length != 2) {
print ("Usage: %s PLUGIN-PATH\n", args[0]);
return 0;
}
try {
PluginLoader loader = new PluginLoader ();
PluginIface plugin = loader.load (args[1]);
plugin.activated ();
} catch (PluginError e) {
print ("Error: %s\n", e.message);
}
return 0;
}
valac application.vala libshared.vapi --pkg gmodule-2.0 -X libshared.so -X -I.
LD_LIBRARY_PATH=. ./application libmyplugin