* Copyright (C) 2011-2020 Gary Kramlich <grim@reaperworld.com> * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * This library 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 * Lesser General Public License for more details. * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, see <https://www.gnu.org/licenses/>. #include <glib/gi18n-lib.h> #include <gplugin/gplugin-core.h> #include <gplugin/gplugin-loader.h> #include <gplugin/gplugin-manager.h> #include <gplugin/gplugin-native-plugin.h> * SECTION:gplugin-native-plugin * @title: Native Plugin API * @short_description: the native plugin API * This section contains the native plugin API of GPlugin. * GPLUGIN_TYPE_NATIVE_PLUGIN: * The standard _get_type macro for #GPluginNativePlugin. * An instance of a loaded native plugin. A native plugin is a plugin that was * compiled to machine native code, typically these are written in C/C++. * GPluginNativePluginQueryFunc: * @error: A return address for a #GError. * Specifies the function signature for the query function of a plugin. * Returns: (transfer full): A #GPluginPluginInfo instance on success or %NULL * with @error set on error. * GPluginNativePluginLoadFunc: * @plugin: The #GPluginPlugin instance. * @error: A return address for a #GError. * Specifies the function signature for the load function of a plugin. * Returns: %TRUE if @plugin was successfully loaded, or %FALSE with @error * GPluginNativePluginUnloadFunc: * @plugin: The #GPluginPlugin instance. * @error: A return address for a #GError. * Specifies the function signature for the unload function of a plugin. * Returns: %TRUE if @plugin was successfully unloaded, or %FALSE with @error /* Apparently clang-format also tries to format code in comments.. But in this * case it makes it really difficult to understand so we disable it. * GPLUGIN_NATIVE_PLUGIN_DECLARE: * @name: The prefix of the user defined function names. * This macro expands to the proper functions that #GPluginNativeLoader looks * for when querying a plugin. They will call user defined functions named * <function>${name}_query</function>, <function>${name}_load</function>, * and <function>${name}_unload</function> which need to match the signatures * of #GPluginNativePluginQueryFunc, #GPluginNativePluginLoadFunc, and * #GPluginNativePluginUnloadFunc. * This macro should be used over manually exporting the individual functions * to help with updates as well as future features like static plugin loading. * <informalexample><programlisting> * GPLUGIN_NATIVE_PLUGIN_DECLARE(my_awesome_plugin) * </programlisting></informalexample> * <informalexample><programlisting> * G_MODULE_EXPORT GPluginPluginInfo *gplugin_query(GError **error); * G_MODULE_EXPORT GPluginPluginInfo *gplugin_query(GError **error) { * return my_awesome_plugin_query(error); * G_MODULE_EXPORT gboolean gplugin_load(GPluginPlugin *plugin, GError **error); * G_MODULE_EXPORT gboolean gplugin_load(GPluginPlugin *plugin, GError **error) { * return my_awesome_plugin_load(error); * G_MODULE_EXPORT gboolean gplugin_unload(GPluginPlugin *plugin, GError **error); * G_MODULE_EXPORT gboolean gplugin_unload(GPluginPlugin *plugin, GError **error) { * return my_awesome_plugin_unload(plugin, error); * </programlisting></informalexample> /****************************************************************************** *****************************************************************************/ struct _GPluginNativePlugin { GPluginPluginState state; /****************************************************************************** *****************************************************************************/ PROP_FILENAME = N_PROPERTIES, static GParamSpec *properties[N_PROPERTIES] = { /****************************************************************************** * GPluginPlugin Implementation *****************************************************************************/ gplugin_native_plugin_iface_init(G_GNUC_UNUSED GPluginPluginInterface *iface) /* we just override properites from GPluginPlugin */ /****************************************************************************** * GTypeModule Implementation *****************************************************************************/ gplugin_native_plugin_load(G_GNUC_UNUSED GTypeModule *module) gplugin_native_plugin_unload(G_GNUC_UNUSED GTypeModule *module) /****************************************************************************** *****************************************************************************/ gplugin_native_plugin_iface_init)); gplugin_native_plugin_get_property( GPluginNativePlugin *plugin = GPLUGIN_NATIVE_PLUGIN(obj); gplugin_native_plugin_get_module(plugin)); g_value_set_pointer(value, plugin->load_func); g_value_set_pointer(value, plugin->unload_func); g_value_set_string(value, plugin->filename); g_value_set_object(value, plugin->loader); g_value_set_object(value, plugin->info); g_value_set_enum(value, plugin->state); g_value_set_boxed(value, plugin->error); G_OBJECT_WARN_INVALID_PROPERTY_ID(obj, param_id, pspec); gplugin_native_plugin_set_property( GPluginNativePlugin *plugin = GPLUGIN_NATIVE_PLUGIN(obj); plugin->module = g_value_get_pointer(value); plugin->load_func = g_value_get_pointer(value); plugin->unload_func = g_value_get_pointer(value); plugin->filename = g_value_dup_string(value); plugin->loader = g_value_dup_object(value); plugin->info = g_value_dup_object(value); plugin->state = g_value_get_enum(value); g_clear_error(&plugin->error); plugin->error = g_value_dup_boxed(value); G_OBJECT_WARN_INVALID_PROPERTY_ID(obj, param_id, pspec); gplugin_native_plugin_finalize(GObject *obj) GPluginNativePlugin *plugin = GPLUGIN_NATIVE_PLUGIN(obj); g_clear_pointer(&plugin->filename, g_free); g_clear_object(&plugin->loader); g_clear_object(&plugin->info); g_clear_error(&plugin->error); g_module_close(plugin->module); G_OBJECT_CLASS(gplugin_native_plugin_parent_class)->finalize(obj); gplugin_native_plugin_init(G_GNUC_UNUSED GPluginNativePlugin *plugin) gplugin_native_plugin_class_init(GPluginNativePluginClass *klass) GObjectClass *obj_class = G_OBJECT_CLASS(klass); GTypeModuleClass *module_class = G_TYPE_MODULE_CLASS(klass); obj_class->finalize = gplugin_native_plugin_finalize; obj_class->get_property = gplugin_native_plugin_get_property; obj_class->set_property = gplugin_native_plugin_set_property; module_class->load = gplugin_native_plugin_load; module_class->unload = gplugin_native_plugin_unload; * GPluginNativePlugin:module: * The GModule instance for this plugin. properties[PROP_MODULE] = g_param_spec_pointer( "The GModule instance of the plugin", G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY); * GPluginNativePlugin:load-func: * A function pointer to the load method of the plugin. properties[PROP_LOAD_FUNC] = g_param_spec_pointer( "address pointer to load function", G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY); * GPluginNativePlugin:unload-func: * A function pointer to the unload method of the plugin. properties[PROP_UNLOAD_FUNC] = g_param_spec_pointer( "unload function pointer", "address pointer to the unload function", G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY); g_object_class_install_properties(obj_class, N_PROPERTIES, properties); g_object_class_override_property(obj_class, PROP_FILENAME, "filename"); g_object_class_override_property(obj_class, PROP_LOADER, "loader"); g_object_class_override_property(obj_class, PROP_INFO, "info"); g_object_class_override_property(obj_class, PROP_STATE, "state"); g_object_class_override_property(obj_class, PROP_ERROR, "error"); /****************************************************************************** *****************************************************************************/ * gplugin_native_plugin_get_module: (skip) * @plugin: #GPluginNativePlugin instance * Returns the %GModule associated with this plugin. This should really only * be used if you need to make your plugin resident. * Returns: The %GModule associated with this plugin. gplugin_native_plugin_get_module(GPluginNativePlugin *plugin) g_return_val_if_fail(GPLUGIN_IS_NATIVE_PLUGIN(plugin), NULL);