[nautilus-actions] Define one test program for dynamic modules
- From: Pierre Wieser <pwieser src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [nautilus-actions] Define one test program for dynamic modules
- Date: Wed, 19 Jan 2011 21:55:14 +0000 (UTC)
commit 19bd842b47ade454292d6a739ddd10f697c98fd5
Author: Pierre Wieser <pwieser trychlos org>
Date: Sun Jan 16 01:22:49 2011 +0100
Define one test program for dynamic modules
ChangeLog | 6 +
src/test/.gitignore | 1 +
src/test/Makefile.am | 28 +++
src/test/test-module-plugin.c | 280 ++++++++++++++++++++++++++
src/test/test-module.c | 447 +++++++++++++++++++++++++++++++++++++++++
5 files changed, 762 insertions(+), 0 deletions(-)
---
diff --git a/ChangeLog b/ChangeLog
index 8f33df6..eb385e5 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -25,6 +25,12 @@
2011-01-15 Pierre Wieser <pwieser trychlos org>
+ * src/test/test-module.c:
+ * src/test/test-module-plugin.c: New files.
+
+ * src/test/.gitignore:
+ * src/test/Makefile.am: Updated accordingly.
+
* src/nact/nact-schemes-list.c: Remove gconf-client.h include.
* src/nact/base-iprefs.c
diff --git a/src/test/.gitignore b/src/test/.gitignore
index 8b89352..9fe4ee7 100644
--- a/src/test/.gitignore
+++ b/src/test/.gitignore
@@ -1,3 +1,4 @@
+test-module
test-parse-uris
test-reader
test-virtuals
diff --git a/src/test/Makefile.am b/src/test/Makefile.am
index 8d6d8d0..d297d48 100644
--- a/src/test/Makefile.am
+++ b/src/test/Makefile.am
@@ -38,6 +38,7 @@ AM_CPPFLAGS += \
-I $(top_srcdir) \
-I $(top_srcdir)/src \
-DGNOMELOCALEDIR=\""$(datadir)/locale"\" \
+ -DPKGLIBDIR=\""$(pkglibdir)"\" \
-DG_LOG_DOMAIN=\"${NA_LOGDOMAIN_TEST}\" \
$(NAUTILUS_ACTIONS_CFLAGS) \
$(NULL)
@@ -65,6 +66,33 @@ test_iface_LDADD = \
$(NAUTILUS_ACTIONS_LIBS) \
$(NULL)
+if NA_MAINTAINER_MODE
+noinst_PROGRAMS += test-module
+pkglib_LTLIBRARIES = libtest_module_plugin.la
+
+test_module_SOURCES = \
+ test-module.c \
+ $(NULL)
+
+test_module_LDADD = \
+ $(NAUTILUS_ACTIONS_LIBS) \
+ $(NULL)
+
+libtest_module_plugin_la_SOURCES = \
+ test-module-plugin.c \
+ $(NULL)
+
+libtest_module_plugin_la_LIBADD = \
+ $(NAUTILUS_ACTIONS_LIBS) \
+ $(NULL)
+
+libtest_module_plugin_la_LDFLAGS = \
+ -module \
+ -no-undefined \
+ -avoid-version \
+ $(NULL)
+endif
+
test_parse_uris_SOURCES = \
test-parse-uris.c \
$(NULL)
diff --git a/src/test/test-module-plugin.c b/src/test/test-module-plugin.c
new file mode 100755
index 0000000..c9f59c5
--- /dev/null
+++ b/src/test/test-module-plugin.c
@@ -0,0 +1,280 @@
+/*
+ * Nautilus-Actions
+ * A Nautilus extension which offers configurable context menu actions.
+ *
+ * Copyright (C) 2005 The GNOME Foundation
+ * Copyright (C) 2006, 2007, 2008 Frederic Ruaudel and others (see AUTHORS)
+ * Copyright (C) 2009, 2010, 2011 Pierre Wieser and others (see AUTHORS)
+ *
+ * This Program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This Program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this Library; see the file COPYING. If not,
+ * write to the Free Software Foundation, Inc., 59 Temple Place,
+ * Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * Authors:
+ * Frederic Ruaudel <grumz grumz net>
+ * Rodrigo Moya <rodrigo gnome-db org>
+ * Pierre Wieser <pwieser trychlos org>
+ * ... and many others (see AUTHORS)
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <glib-object.h>
+#include <gmodule.h>
+
+/* this is a plugin, i.e. a dynamically loaded resource
+ */
+
+G_MODULE_EXPORT const gchar *g_module_check_init( GModule *module );
+G_MODULE_EXPORT void g_module_unload( GModule *module );
+
+#if 0
+/* this is first version
+ * the module is loaded, the function called, and then the module is unloaded
+ * note that we do not define any GType here, so do not provide any sort of
+ * GInterface implementation
+ *
+ (process:23911): NA-test-DEBUG: in g_module_check_init: module=0xf97f20
+ (process:23911): NA-test-DEBUG: say_hello: module=0xf97f20
+ (process:23911): NA-test-DEBUG: in g_module_unload: module=0xf97f20
+ *
+ */
+
+G_MODULE_EXPORT void say_hello( GModule *module );
+
+/* automatically called when the module is loaded
+ */
+G_MODULE_EXPORT const gchar *
+g_module_check_init( GModule *module )
+{
+ const gchar *error;
+
+ error = NULL;
+ g_debug( "in g_module_check_init: module=%p", ( void * ) module );
+
+ return( error );
+}
+
+/* automatically called when the module is unloaded
+ */
+G_MODULE_EXPORT void
+g_module_unload( GModule *module )
+{
+ g_debug( "in g_module_unload: module=%p", ( void * ) module );
+}
+
+/* a function dynamically called from the program
+ */
+G_MODULE_EXPORT void
+say_hello( GModule *module )
+{
+ g_debug( "say_hello: module=%p", ( void * ) module );
+}
+#endif
+
+/* version 2
+ * define the module as a GTypeModule-derived one
+ */
+#define TEST_MODULE_PLUGIN_TYPE ( na_module_plugin_get_type())
+#define TEST_MODULE_PLUGIN( object ) ( G_TYPE_CHECK_INSTANCE_CAST( object, TEST_MODULE_PLUGIN_TYPE, NAModulePlugin ))
+#define TEST_MODULE_PLUGIN_CLASS( klass ) ( G_TYPE_CHECK_CLASS_CAST( klass, TEST_MODULE_PLUGIN_TYPE, NAModulePluginClass ))
+#define TEST_IS_MODULE_PLUGIN( object ) ( G_TYPE_CHECK_INSTANCE_TYPE( object, TEST_MODULE_PLUGIN_TYPE ))
+#define TEST_IS_MODULE_PLUGIN_CLASS( klass ) ( G_TYPE_CHECK_CLASS_TYPE(( klass ), TEST_MODULE_PLUGIN_TYPE ))
+#define TEST_MODULE_PLUGIN_GET_CLASS( object ) ( G_TYPE_INSTANCE_GET_CLASS(( object ), TEST_MODULE_PLUGIN_TYPE, NAModulePluginClass ))
+
+typedef struct _NAModulePluginPrivate NAModulePluginPrivate;
+typedef struct _NAModulePluginClassPrivate NAModulePluginClassPrivate;
+
+typedef struct {
+ GObject parent;
+ NAModulePluginPrivate *private;
+}
+ NAModulePlugin;
+
+typedef struct {
+ GObjectClass parent;
+ NAModulePluginClassPrivate *private;
+}
+ NAModulePluginClass;
+
+GType na_module_plugin_get_type( void );
+
+/* private instance data
+ */
+struct _NAModulePluginPrivate {
+ gboolean dispose_has_run;
+};
+
+/* private class data
+ */
+struct _NAModulePluginClassPrivate {
+ void *empty; /* so that gcc -pedantic is happy */
+};
+
+static GType st_module_type = 0;
+static GTypeModuleClass *st_parent_class = NULL;
+
+static void na_module_plugin_register_type( GTypeModule *module );
+static void class_init( NAModulePluginClass *klass );
+static void instance_init( GTypeInstance *instance, gpointer klass );
+static void instance_dispose( GObject *object );
+static void instance_finalize( GObject *object );
+
+G_MODULE_EXPORT void plugin_init( GTypeModule *module );
+
+GType
+na_module_plugin_get_type( void )
+{
+ return( st_module_type );
+}
+
+static void
+na_module_plugin_register_type( GTypeModule *module )
+{
+ static const gchar *thisfn = "na_module_plugin_register_type";
+
+ static GTypeInfo info = {
+ sizeof( NAModulePluginClass ),
+ NULL,
+ NULL,
+ ( GClassInitFunc ) class_init,
+ NULL,
+ NULL,
+ sizeof( NAModulePlugin ),
+ 0,
+ ( GInstanceInitFunc ) instance_init
+ };
+
+ /*static const GInterfaceInfo iio_provider_iface_info = {
+ ( GInterfaceInitFunc ) iio_provider_iface_init,
+ NULL,
+ NULL
+ };*/
+
+ g_debug( "%s", thisfn );
+
+ st_module_type = g_type_module_register_type( module, G_TYPE_OBJECT, "NAModulePlugin", &info, 0 );
+
+ /*g_type_module_add_interface( module, st_module_type, NA_IIO_PROVIDER_TYPE, &iio_provider_iface_info );*/
+}
+
+static void
+class_init( NAModulePluginClass *klass )
+{
+ static const gchar *thisfn = "na_module_plugin_class_init";
+ GObjectClass *object_class;
+
+ g_debug( "%s: klass=%p", thisfn, ( void * ) klass );
+
+ st_parent_class = g_type_class_peek_parent( klass );
+
+ object_class = G_OBJECT_CLASS( klass );
+ object_class->dispose = instance_dispose;
+ object_class->finalize = instance_finalize;
+
+ klass->private = g_new0( NAModulePluginClassPrivate, 1 );
+}
+
+static void
+instance_init( GTypeInstance *instance, gpointer klass )
+{
+ static const gchar *thisfn = "na_module_plugin_instance_init";
+ NAModulePlugin *self;
+
+ g_return_if_fail( TEST_IS_MODULE_PLUGIN( instance ));
+
+ g_debug( "%s: instance=%p (%s), klass=%p",
+ thisfn, ( void * ) instance, G_OBJECT_TYPE_NAME( instance ), ( void * ) klass );
+
+ self = TEST_MODULE_PLUGIN( instance );
+
+ self->private = g_new0( NAModulePluginPrivate, 1 );
+
+ self->private->dispose_has_run = FALSE;
+}
+
+static void
+instance_dispose( GObject *object )
+{
+ static const gchar *thisfn = "na_module_plugin_instance_dispose";
+ NAModulePlugin *self;
+
+ g_return_if_fail( TEST_IS_MODULE_PLUGIN( object ));
+
+ self = TEST_MODULE_PLUGIN( object );
+
+ if( !self->private->dispose_has_run ){
+
+ g_debug( "%s: object=%p (%s)", thisfn, ( void * ) object, G_OBJECT_TYPE_NAME( object ));
+
+ self->private->dispose_has_run = TRUE;
+
+ /* chain up to the parent class */
+ if( G_OBJECT_CLASS( st_parent_class )->dispose ){
+ G_OBJECT_CLASS( st_parent_class )->dispose( object );
+ }
+ }
+}
+
+static void
+instance_finalize( GObject *object )
+{
+ static const gchar *thisfn = "na_test_module_plugin_instance_finalize";
+ NAModulePlugin *self;
+
+ g_return_if_fail( TEST_IS_MODULE_PLUGIN( object ));
+
+ g_debug( "%s: object=%p (%s)", thisfn, ( void * ) object, G_OBJECT_TYPE_NAME( object ));
+
+ self = TEST_MODULE_PLUGIN( object );
+
+ g_free( self->private );
+
+ /* chain call to parent class */
+ if( G_OBJECT_CLASS( st_parent_class )->finalize ){
+ G_OBJECT_CLASS( st_parent_class )->finalize( object );
+ }
+}
+
+/* automatically called when the module is loaded
+ * this is very less useful in this version as we need a GTypeModule to register
+ * our dynamic types
+ */
+G_MODULE_EXPORT const gchar *
+g_module_check_init( GModule *module )
+{
+ g_debug( "in g_module_check_init: module=%p", ( void * ) module );
+ return( NULL );
+}
+
+/* automatically called when the module is unloaded
+ */
+G_MODULE_EXPORT void
+g_module_unload( GModule *module )
+{
+ g_debug( "in g_module_unload: module=%p", ( void * ) module );
+}
+
+/* module is actually a NAModule, but we do not care of that
+ * registering the type - but do not yet allocate an object
+ */
+G_MODULE_EXPORT void
+plugin_init( GTypeModule *module )
+{
+ g_debug( "plugin_init: module=%p", ( void * ) module );
+
+ na_module_plugin_register_type( module );
+}
diff --git a/src/test/test-module.c b/src/test/test-module.c
new file mode 100755
index 0000000..943f0a2
--- /dev/null
+++ b/src/test/test-module.c
@@ -0,0 +1,447 @@
+/*
+ * Nautilus-Actions
+ * A Nautilus extension which offers configurable context menu actions.
+ *
+ * Copyright (C) 2005 The GNOME Foundation
+ * Copyright (C) 2006, 2007, 2008 Frederic Ruaudel and others (see AUTHORS)
+ * Copyright (C) 2009, 2010, 2011 Pierre Wieser and others (see AUTHORS)
+ *
+ * This Program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This Program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this Library; see the file COPYING. If not,
+ * write to the Free Software Foundation, Inc., 59 Temple Place,
+ * Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * Authors:
+ * Frederic Ruaudel <grumz grumz net>
+ * Rodrigo Moya <rodrigo gnome-db org>
+ * Pierre Wieser <pwieser trychlos org>
+ * ... and many others (see AUTHORS)
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+/* this is a module to test how to use the GLib dynamic-loading functions
+ * it tries to load, then unload, a test-module-plugin.so plugin
+ *
+ * more specifically, I am interested on releasing allocated resources
+ */
+
+#include <stdlib.h>
+
+#include <glib-object.h>
+#include <gmodule.h>
+
+#define PLUGIN_NAME "test_module_plugin"
+
+
+#if 0
+/* this is first version
+ */
+static GModule *load_plugin( void );
+static void call_plugin_fn( GModule *module );
+static void unload_plugin( GModule *module );
+
+int
+main( int argc, char **argv )
+{
+ GModule *module;
+
+ g_type_init();
+
+ /* dynamically load the module */
+ module = load_plugin();
+
+ if( module ){
+ /* call a function in the module */
+ call_plugin_fn( module );
+
+ /* unload the module */
+ unload_plugin( module );
+ }
+
+ return( 0 );
+}
+
+static GModule *
+load_plugin( void )
+{
+ gchar *module_path;
+ GModule *module;
+
+ module = NULL;
+
+ if( g_module_supported()){
+
+ module_path = g_module_build_path( PKGLIBDIR, PLUGIN_NAME );
+ module = g_module_open( module_path, G_MODULE_BIND_LAZY | G_MODULE_BIND_LOCAL );
+ if( !module ){
+ g_printerr( "%s: %s\n", module_path, g_module_error());
+ }
+ g_free( module_path );
+ }
+
+ return( module );
+}
+
+static void
+call_plugin_fn( GModule *module )
+{
+ typedef void ( *PluginFn )( GModule *module );
+ PluginFn plugin_fn;
+
+ if( !g_module_symbol( module, "say_hello", ( gpointer * ) &plugin_fn )){
+ g_printerr( "%s\n", g_module_error());
+ return;
+ }
+ if( !plugin_fn ){
+ g_printerr( "%s\n", g_module_error());
+ return;
+ }
+ plugin_fn( module );
+}
+
+static void
+unload_plugin( GModule *module )
+{
+ if( !g_module_close( module )){
+ g_printerr( "%s\n", g_module_error());
+ }
+}
+#endif
+
+/* version 2
+ * Having the plugin register dynamic GTypes require a GTypeModule
+ * This GTtypeModule is provided by the program as a GTypeModule-derived object
+ * NAModule embeds the GModule
+ *
+ * Result:
+ *
+ * - the main program (the loader) should define a GTypeModule derived class
+ *
+ * - the GTypeModule derived class (here NAModule) embeds a GModule pointer
+ *
+ * - when loading plugins:
+ *
+ * > allocate a new GTypeModule derived object for each module
+ * setup the path here
+ *
+ * > g_type_module_use() it
+ * this triggers the on_load() virtual method on GTypeModule derived class
+ * in on_load_derived(), g_module_open() the plugin and check the API
+ *
+ * on_load_derived() may return FALSE
+ * while dynamic types have not been registered, we are always safe to unref
+ * the allocated GTypeModule derived object
+ * setup the GModule pointer on the loaded library
+ *
+ * so, if g_module_use() returns FALSE, just unref the object
+ *
+ * so, g_module_use() cannot be called from instance_init or
+ * instance_constructed (which have no return value)
+ *
+ * At the end, it is impossible to release the GTypeModule objects.
+ * But we can safely unuse their loaded libraries.
+ *
+ * The main program does not known which GType or GInterface the plugin
+ * declares.
+ * Nautilus defines a get_types() API, and then allocates an object for each
+ * returned type. It is then easy to check if the object implements a given
+ * interface.
+ * Nautilus never release these objects.
+ * We may also ask the plugin to just allocate itself its own management object,
+ * returning it to the program (returning a pointer is possible because we are
+ * in the same process).
+ */
+
+#define NA_MODULE_TYPE ( na_module_get_type())
+#define NA_MODULE( object ) ( G_TYPE_CHECK_INSTANCE_CAST( object, NA_MODULE_TYPE, NAModule ))
+#define NA_MODULE_CLASS( klass ) ( G_TYPE_CHECK_CLASS_CAST( klass, NA_MODULE_TYPE, NAModuleClass ))
+#define NA_IS_MODULE( object ) ( G_TYPE_CHECK_INSTANCE_TYPE( object, NA_MODULE_TYPE ))
+#define NA_IS_MODULE_CLASS( klass ) ( G_TYPE_CHECK_CLASS_TYPE(( klass ), NA_MODULE_TYPE ))
+#define NA_MODULE_GET_CLASS( object ) ( G_TYPE_INSTANCE_GET_CLASS(( object ), NA_MODULE_TYPE, NAModuleClass ))
+
+typedef struct _NAModulePrivate NAModulePrivate;
+typedef struct _NAModuleClassPrivate NAModuleClassPrivate;
+
+typedef struct {
+ /*< private >*/
+ GTypeModule parent;
+ NAModulePrivate *private;
+}
+ NAModule;
+
+typedef struct {
+ /*< private >*/
+ GTypeModuleClass parent;
+ NAModuleClassPrivate *private;
+}
+ NAModuleClass;
+
+GType na_module_get_type ( void );
+
+/* private class data
+ */
+struct _NAModuleClassPrivate {
+ void *empty; /* so that gcc -pedantic is happy */
+};
+
+/* private instance data
+ */
+struct _NAModulePrivate {
+ gboolean dispose_has_run;
+ GModule *plugin;
+};
+
+static GTypeModuleClass *st_parent_class = NULL;
+
+static GType register_type( void );
+static void class_init( NAModuleClass *klass );
+static void instance_init( GTypeInstance *instance, gpointer klass );
+static void instance_dispose( GObject *object );
+static void instance_finalize( GObject *object );
+
+static NAModule *load_plugin( void );
+static gboolean on_module_load( GTypeModule *module );
+static void call_plugin_fn( NAModule *module );
+static void on_unload_plugin( GTypeModule *module );
+
+GType
+na_module_get_type( void )
+{
+ static GType object_type = 0;
+
+ if( !object_type ){
+ object_type = register_type();
+ }
+
+ return( object_type );
+}
+
+static GType
+register_type( void )
+{
+ static const gchar *thisfn = "na_module_register_type";
+ GType type;
+
+ static GTypeInfo info = {
+ sizeof( NAModuleClass ),
+ ( GBaseInitFunc ) NULL,
+ ( GBaseFinalizeFunc ) NULL,
+ ( GClassInitFunc ) class_init,
+ NULL,
+ NULL,
+ sizeof( NAModule ),
+ 0,
+ ( GInstanceInitFunc ) instance_init
+ };
+
+ g_debug( "%s", thisfn );
+
+ type = g_type_register_static( G_TYPE_TYPE_MODULE, "NAModule", &info, 0 );
+
+ return( type );
+}
+
+static void
+class_init( NAModuleClass *klass )
+{
+ static const gchar *thisfn = "na_module_class_init";
+ GObjectClass *object_class;
+ GTypeModuleClass *module_class;
+
+ g_debug( "%s: klass=%p", thisfn, ( void * ) klass );
+
+ st_parent_class = g_type_class_peek_parent( klass );
+
+ object_class = G_OBJECT_CLASS( klass );
+ object_class->dispose = instance_dispose;
+ object_class->finalize = instance_finalize;
+
+ module_class = G_TYPE_MODULE_CLASS( klass );
+ module_class->load = on_module_load;
+ module_class->unload = on_unload_plugin;
+
+ klass->private = g_new0( NAModuleClassPrivate, 1 );
+}
+
+static void
+instance_init( GTypeInstance *instance, gpointer klass )
+{
+ static const gchar *thisfn = "na_module_instance_init";
+ NAModule *self;
+
+ g_return_if_fail( NA_IS_MODULE( instance ));
+
+ g_debug( "%s: instance=%p (%s), klass=%p",
+ thisfn, ( void * ) instance, G_OBJECT_TYPE_NAME( instance ), ( void * ) klass );
+
+ self = NA_MODULE( instance );
+
+ self->private = g_new0( NAModulePrivate, 1 );
+
+ self->private->dispose_has_run = FALSE;
+}
+
+static void
+instance_dispose( GObject *object )
+{
+ static const gchar *thisfn = "na_module_instance_dispose";
+ NAModule *self;
+
+ g_return_if_fail( NA_IS_MODULE( object ));
+
+ self = NA_MODULE( object );
+
+ if( !self->private->dispose_has_run ){
+
+ g_debug( "%s: object=%p (%s)", thisfn, ( void * ) object, G_OBJECT_TYPE_NAME( object ));
+
+ self->private->dispose_has_run = TRUE;
+
+ /* should trigger unload of the plugin */
+ /* refused by GLib
+ * GLib-GObject-WARNING **: gtypemodule.c:111: unsolicitated invocation of g_object_dispose() on GTypeModule
+ */
+ /*g_type_module_unuse( G_TYPE_MODULE( self ));*/
+
+ if( G_OBJECT_CLASS( st_parent_class )->dispose ){
+ G_OBJECT_CLASS( st_parent_class )->dispose( object );
+ }
+ }
+}
+
+static void
+instance_finalize( GObject *object )
+{
+ static const gchar *thisfn = "na_module_instance_finalize";
+ NAModule *self;
+
+ g_return_if_fail( NA_IS_MODULE( object ));
+
+ g_debug( "%s: object=%p (%s)", thisfn, ( void * ) object, G_OBJECT_TYPE_NAME( object ));
+
+ self = NA_MODULE( object );
+
+ g_free( self->private );
+
+ /* chain call to parent class */
+ if( G_OBJECT_CLASS( st_parent_class )->finalize ){
+ G_OBJECT_CLASS( st_parent_class )->finalize( object );
+ }
+}
+
+int
+main( int argc, char **argv )
+{
+ NAModule *module;
+
+ g_type_init();
+
+ /* dynamically load the module */
+ module = load_plugin();
+
+ if( module ){
+ /* call a function in the module */
+ call_plugin_fn( module );
+
+ /* try to just unref the NAModule */
+ /* not ok */
+ /*g_object_unref( module );*/
+
+ /* try to unload the plugin */
+ g_type_module_unuse( G_TYPE_MODULE( module ));
+ /* then unref the object */
+ /* not ok
+ * it happens that releasing the GTypeModule after having registered a GType or a
+ * GInterface is impossible
+ * see http://git.gnome.org/browse/glib/tree/gobject/gtypemodule.c
+ * and http://library.gnome.org/devel/gobject/unstable/GTypeModule.html#g-type-module-unuse
+ */
+ /*g_object_unref( module );*/
+ }
+
+ return( 0 );
+}
+
+static NAModule *
+load_plugin( void )
+{
+ NAModule *module;
+
+ module = NULL;
+
+ if( g_module_supported()){
+
+ module = g_object_new( NA_MODULE_TYPE, NULL );
+ g_debug( "test_module_load_plugin: module=%p", ( void * ) module );
+
+ if( !g_type_module_use( G_TYPE_MODULE( module ))){
+ g_object_unref( module );
+ }
+ }
+
+ return( module );
+}
+
+static gboolean
+on_module_load( GTypeModule *module )
+{
+ gboolean ok;
+ gchar *module_path;
+ NAModule *na_module = NA_MODULE( module );
+
+ g_debug( "test_module_on_module_load" );
+
+ ok = TRUE;
+ module_path = g_module_build_path( PKGLIBDIR, PLUGIN_NAME );
+
+ g_debug( "test_module_on_module_load: opening the library" );
+ na_module->private->plugin = g_module_open( module_path, G_MODULE_BIND_LAZY | G_MODULE_BIND_LOCAL );
+
+ if( !na_module->private->plugin ){
+ g_printerr( "%s: %s\n", module_path, g_module_error());
+ ok = FALSE;
+ }
+
+ g_free( module_path );
+
+ return( ok );
+}
+
+static void
+call_plugin_fn( NAModule *module )
+{
+ typedef void ( *PluginInit )( NAModule *module );
+ PluginInit plugin_fn;
+
+ if( !g_module_symbol( module->private->plugin, "plugin_init", ( gpointer * ) &plugin_fn )){
+ g_printerr( "%s\n", g_module_error());
+ return;
+ }
+ if( !plugin_fn ){
+ g_printerr( "%s\n", g_module_error());
+ return;
+ }
+ plugin_fn( module );
+}
+
+static void
+on_unload_plugin( GTypeModule *module )
+{
+ g_debug( "test_module_on_unload_plugin" );
+ if( !g_module_close( NA_MODULE( module )->private->plugin )){
+ g_printerr( "%s\n", g_module_error());
+ }
+}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]