The OpenNET Project / Index page

[ новости /+++ | форум | wiki | теги | ]

Каталог документации / Раздел "Программирование, языки" / Оглавление документа

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

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




Спонсоры:
Inferno Solutions
Hosting by Hoster.ru
Хостинг:

Закладки на сайте
Проследить за страницей
Created 1996-2021 by Maxim Chirkov
Добавить, Поддержать, Вебмастеру