parent
c3f59d781d
commit
1eec145586
5 changed files with 106 additions and 0 deletions
@ -0,0 +1,17 @@ |
||||
public extern const string FOO_PLUGIN_PATH; |
||||
|
||||
Foo.PluginModule plugin_module; |
||||
|
||||
public int main () { |
||||
plugin_module = new Foo.PluginModule (FOO_PLUGIN_PATH, "bar"); |
||||
|
||||
if (!plugin_module.load ()) { |
||||
return 1; |
||||
} |
||||
|
||||
var plugin = Object.new (plugin_module.plugin_type) as Foo.Plugin; |
||||
|
||||
assert ("bar" == plugin.bar ()); |
||||
|
||||
return 0; |
||||
} |
@ -0,0 +1,20 @@ |
||||
project('valatest', 'c', 'vala') |
||||
|
||||
glib_dep = dependency('glib-2.0') |
||||
gobject_dep = dependency('gobject-2.0') |
||||
gmodule_dep = dependency('gmodule-2.0') |
||||
|
||||
foo_sources = ['plugin.vala', 'plugin-module.vala'] |
||||
foo_lib = shared_library('foo', foo_sources, |
||||
dependencies: [glib_dep, gobject_dep, gmodule_dep]) |
||||
|
||||
shared_module('bar', 'plugin-bar.vala', |
||||
dependencies: [glib_dep, gobject_dep], |
||||
link_with: foo_lib) |
||||
|
||||
foo_bin = executable('foo', 'foo.vala', |
||||
c_args: ['-DFOO_PLUGIN_PATH="@0@"'.format(meson.current_build_dir())], |
||||
dependencies: [glib_dep, gobject_dep], |
||||
link_with: foo_lib) |
||||
|
||||
test('shared module', foo_bin) |
@ -0,0 +1,11 @@ |
||||
[ModuleInit] |
||||
public GLib.Type plugin_init (GLib.TypeModule tm) { |
||||
return typeof (Bar.Plugin); |
||||
} |
||||
|
||||
public class Bar.Plugin : Foo.Plugin, GLib.Object { |
||||
|
||||
public string bar () { |
||||
return "bar"; |
||||
} |
||||
} |
@ -0,0 +1,54 @@ |
||||
public class Foo.PluginModule : TypeModule { |
||||
|
||||
[CCode (has_target = false)] |
||||
private delegate Type PluginInit (TypeModule type_module); |
||||
|
||||
public string? directory { get; construct; default = null; } |
||||
|
||||
public string name { get; construct; } |
||||
|
||||
public string path { get; construct; } |
||||
|
||||
public Type plugin_type { get; private set; } |
||||
|
||||
private Module? module = null; |
||||
|
||||
public PluginModule (string? directory, string name) { |
||||
Object (directory: directory, name: name); |
||||
} |
||||
|
||||
construct { |
||||
path = Module.build_path (directory, name); |
||||
} |
||||
|
||||
public override bool load () { |
||||
module = Module.open (path, ModuleFlags.BIND_LAZY); |
||||
|
||||
if (module == null) { |
||||
critical (Module.error ()); |
||||
return false; |
||||
} |
||||
|
||||
void* plugin_init; |
||||
if (!module.symbol ("plugin_init", out plugin_init)){ |
||||
critical (Module.error ()); |
||||
return false; |
||||
} |
||||
|
||||
if (plugin_init == null) { |
||||
return false; |
||||
} |
||||
|
||||
plugin_type = ((PluginInit) plugin_init) (this); |
||||
|
||||
if (!plugin_type.is_a (typeof (Plugin))) { |
||||
return false; |
||||
} |
||||
|
||||
return true; |
||||
} |
||||
|
||||
public override void unload () { |
||||
module = null; |
||||
} |
||||
} |
@ -0,0 +1,4 @@ |
||||
public interface Foo.Plugin : GLib.Object { |
||||
|
||||
public abstract string bar (); |
||||
} |
Loading…
Reference in new issue