Dynamic Loading of Modules

Dynamic Loading of Modules — Переносимый способ для динамической загрузки 'plug-ins'.

Краткое описание

#include <gmodule.h> GModule; gboolean g_module_supported (void); gchar* g_module_build_path (const gchar *directory, const gchar *module_name); GModule* g_module_open (const gchar *file_name, GModuleFlags flags); enum GModuleFlags; gboolean g_module_symbol (GModule *module, const gchar *symbol_name, gpointer *symbol); const gchar* g_module_name (GModule *module); void g_module_make_resident (GModule *module); gboolean g_module_close (GModule *module); const gchar* g_module_error (void); const gchar* (*GModuleCheckInit) (GModule *module); void (*GModuleUnload) (GModule *module); #define G_MODULE_SUFFIX #define G_MODULE_EXPORT #define G_MODULE_IMPORT

Описание

Эти функции обеспечивают переносимый способ динамической загрузки объектных файлов (известны как 'plug-ins'). Текущая реализация поддерживает все системы которые обеспечивают выполнение dlopen() (например Linux/Sun), а также HP-UX через механизм shl_load() и Windows через DLLs.

Программы которые предполагается использовать с этими функциями должны быть слинкованы с библиотеками вывода (output) с помощью команды pkg-config --libs gmodule-2.0.

Для их использования вы сначала должны определить поддерживается ли динамическая загрузка на используемой платформе с помощью вызова g_module_supported(). Если поддерживается, то вы можете открывать модули с помощью g_module_open(), искать модульные идентификаторы (например имена функций) с помощью g_module_symbol(), а затем закрывать модули с помощью g_module_close(). g_module_name() возвращает имя файла текущего открытого модуля.

Если любая из описанных выше функций завершается неудачей, описание ошибки можно найти с помощью g_module_error().

GModule реализует особенность подсчета ссылок для открытых модулей и поддержку функций обработки прерываний в модуле, которая вызывается когда модуль загружается и выгружается (смотрите GModuleCheckInit и GModuleUnload).

Если ваш модуль вводит статические данные для общих подсистем в выполняемой программе, например через вызов g_quark_from_static_string ("my-module-stuff"), он должен быть уверен что никогда не выгрузится с помощью вызова g_module_make_resident().

Пример 12. Calling a function defined in a GModule

/* Подпись функции для 'say_hello' */ typedef void (* SayHelloFunc) (const char *message); gboolean just_say_hello (const char *filename, GError **error) { SayHelloFunc say_hello; GModule *module; module = g_module_open (filename, G_MODULE_BIND_LAZY); if (!module) { g_set_error (error, FOO_ERROR, FOO_ERROR_BLAH, "%s", g_module_error ()); return FALSE; } if (!g_module_symbol (module, "say_hello", (gpointer *)&say_hello)) { g_set_error (error, SAY_ERROR, SAY_ERROR_OPEN, "%s: %s", filename, g_module_error ()); if (!g_module_close (module)) g_warning ("%s: %s", filename, g_module_error ()); return FALSE; } /* вызываем нашу функцию в модуле */ say_hello ("Hello world!"); if (!g_module_close (module)) g_warning ("%s: %s", filename, g_module_error ()); return TRUE; }

Детали

GModule

typedef struct _GModule GModule;

Непрозрачная структура данных GModule представляет Dynamically-Loaded Module. Доступ к ней должен осуществляться только с помощью функций описанных ниже.


g_module_supported ()

gboolean g_module_supported (void);

Проверяет поддерживается ли модуль текущей платформой.

Возвращает : TRUE если модуль поддерживается.

g_module_build_path ()

gchar* g_module_build_path (const gchar *directory, const gchar *module_name);

Переносимый способ создания имени файла модуля. Платформо-специфичные префикс и суффикс добавляются для имени файла, если необходимо и результат добавляется в каталог, используя правильный символьный разделитель.

Параметр directory должен определять каталог где где может быть найден модуль. Он может быть NULL или пустой строкой указывая что модуль находится в стандартном платформо-зависимом каталоге, хотя это не рекомендуется, так как может быть найден неправильный модуль.

Например, вызов g_module_build_path() в системе Linux с параметром directory равным значению /lib и параметром module_name равным значению "mylibrary" вернёт /lib/libmylibrary.so. В системе Windows, использование \Windows как значение параметра directory вернёт \Windows\mylibrary.dll.

directory : каталог где находится модуль. Может быть NULL или пустой строкой указывая что используется стандартный платформо-зависимый каталог, хотя это не рекомендуется.
module_name : имя модуля.
Возвращает : абсолютный путь модуля, включая стандартный библиотечный префикс и суффикс. Должен освобождаться когда больше не нужен.

g_module_open ()

GModule* g_module_open (const gchar *file_name, GModuleFlags flags);

Открывает модуль. Если модуль уже открыт, то увеличивает количество ссылок.

Прежде всего g_module_open() пытается открыть file_name как модуль. Если это не удаётся и file_name имеет суффикс ".la" (и есть архив libtool), она пробует открыть соответствующий модуль. Если терпит неудачу и он не имеет надлежащего суффикса модуля для платформы (G_MODULE_SUFFIX), этот суффикс будет приставлен и соответствующий модуль будет открыт. Если это не удаётся и file_name не имеет суффикса ".la", этот суффикс подставляется и g_module_open() пытается открыть соответствующий модуль. Если и это не удаётся, то возвращается NULL.

file_name : имя файла содержащего модуль, или NULL для получения GModule представляющую непосредственно основную программу.
flags : флаги используемые для открытия модуля. Это может быть логическое ИЛИ любого из GModuleFlags.
Возвращает : GModule если выполнено удачно, или NULL если неудачно.

enum GModuleFlags

typedef enum { G_MODULE_BIND_LAZY = 1 << 0, G_MODULE_BIND_LOCAL = 1 << 1, G_MODULE_BIND_MASK = 0x03 } GModuleFlags;

Флаги помещаемые в g_module_open(). Помните что эти флаги поддерживаются на всех платформах.

G_MODULE_BIND_LAZY определяет что обозначения разрешены только при необходимости. Действие по умолчанию связывает все символы при загрузке модуля.
G_MODULE_BIND_LOCAL определяет что обозначения модуля не должны добавляться к глобальному пространству имён. Действие по умолчанию на большинстве платформ помещает обозначения в модуле в глобальное пространство имён, что может вызвать конфликт с существующими обозначениями.
G_MODULE_BIND_MASK маска для всех флагов.

g_module_symbol ()

gboolean g_module_symbol (GModule *module, const gchar *symbol_name, gpointer *symbol);

Получает указатель символа из модуля.

module : GModule.
symbol_name : символьное имя для поиска.
symbol : возвращает указатель для символьного значения.
Возвращает : TRUE если выполнено.

g_module_name ()

const gchar* g_module_name (GModule *module);

Получает имя файла из GModule.

module : GModule.
Возвращает : имя файла модуля, или "main" если модуль непосредственно основная программа.

g_module_make_resident ()

void g_module_make_resident (GModule *module);

Гарантирует что модуль не будет выгружен. Любые вызовы g_module_close() для модуля будут игнорироваться в последствии.

module : GModule для постоянного нахождения в памяти.

g_module_close ()

gboolean g_module_close (GModule *module);

Закрывает модуль.

module : GModule для закрытия.
Возвращает : TRUE при удачном выполнении.

g_module_error ()

const gchar* g_module_error (void);

Получает строку описывающую последнюю ошибку модуля.

Возвращает : строка описывающая последнюю ошибку модуля.

GModuleCheckInit ()

const gchar* (*GModuleCheckInit) (GModule *module);

Определяет тип функции инициализации модуля. Если модуль содержит функцию с именем g_module_check_init() она вызывается автоматически при загрузке модуля. В неё помещается структура GModule и она должна вернуть NULL при успешном выполнении инициализации, или строку описывающую ошибку.

module : GModule соответствующая только что загруженному модулю.
Возвращает : NULL при успешном выполнении, или строку описывающую ошибку инициализации.

GModuleUnload ()

void (*GModuleUnload) (GModule *module);

Определяет тип модульной функции вызываемой при выгрузке. Если модуль содержит функцию с именем g_module_unload() она вызывается автоматически при выгрузке модуля. В неё помещается структура GModule.

module : GModule который выгружается.

G_MODULE_SUFFIX

#define G_MODULE_SUFFIX "so"

Расширение для надлежащего обще-библиотечного суффикса текущей платформы, без точки. Для большинства версий Uniх и Linux это "so", для некоторых версий HP-UX это "sl", а для Windows это "dll".


G_MODULE_EXPORT

#define G_MODULE_EXPORT

Используется для декларации функций экспортируемых модулями.


G_MODULE_IMPORT

#define G_MODULE_IMPORT extern

Используется для декларации функций импортируемых из модулей.