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

	//private Type type;

	void * plugin_init = null;

	public override bool load () {
		//if (plugin_init != null) return true;
		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");
		}

		if (! module.symbol ("plugin_init", out plugin_init)) {
			error ("No such symbol");
		}

		/*type = */((PluginInitFunc) plugin_init) (this);

		return true;
	}

	public override void unload () {
		if (module != null)
			message ("Library unloaded");
		module = null;
	}

	//public Object create_instance (/*IHost ihost*/) {
	//	var p = Object.new (type) as Object;
	//	//p.host = ihost;
	//	return p;
	//}
}

// Never unref instance of GTypeModule
// http://www.lanedo.com/~mitch/module-system-talk-guadec-2006/Module-System-Talk-Guadec-2006.pdf
static MyModule module = null;

int main ()
{
	module = new MyModule ("plugin");
	module.load ();

	var o = GLib.Object.new (Type.from_name ("MyClass"));

	var vasya = GLib.Object.new (Type.from_name ("MyNameIsVasya"));

	// free last instance, plugin unload
	o = null;

	vasya = null;

	module.unload ();

	return 0;
}
