Spec-Zone.ru › Elisp

Код инициализации модуля

Начните работу с модуля, включив заголовочный файл emacs-module.h и определив символ совместимости GPL:

#include <emacs-module.h>

int plugin_is_GPL_compatible;

Файл emacs-module.h устанавливается в дерево включений вашей системы в составе установки Emacs. В качестве альтернативы, его можно найти в дереве исходного кода Emacs.

Далее напишите функцию инициализации модуля.

Функция: int emacs_module_init (struct emacs_runtime *runtime)

Emacs вызывает эту функцию при загрузке модуля. Если модуль не экспортирует функцию, названную emacs_module_init, попытка загрузить модуль приведет к ошибке. Функция инициализации должна возвращать ноль, если инициализация прошла успешно, и ненулевое значение в противном случае. В последнем случае Emacs выдаст ошибку, и загрузка модуля завершится неудачно. Если пользователь нажмет C-g во время инициализации, Emacs игнорирует возвращаемое значение функции инициализации и завершит работу (см. Выход). (Если нужно, вы можете перехватить выход пользователя внутри функции инициализации, см. should_quit.)

Аргумент runtime — указатель на C struct, который включает 2 публичных поля: size, предоставляющее размер структуры в байтах; и get_environment, предоставляющее указатель на функцию, которая позволяет функции инициализации модуля получить доступ к объекту среды Emacs и его интерфейсам.

Функция инициализации должна выполнить любую необходимую инициализацию модуля. Кроме того, она может выполнить следующие задачи:

Проверка совместимости

Модуль может проверить совместимость исполняемого файла Emacs, который загружает модуль, с модулем, сравнив член size структуры runtime со значением, скомпилированным в модуль:

int
emacs_module_init (struct emacs_runtime *runtime)
{
  if (runtime->size < sizeof (*runtime))
    return 1;
}

Если размер объекта runtime, переданного модулю, меньше ожидаемого, это означает, что модуль был скомпилирован для версии Emacs, более новой (поздней), чем та, которая пытается его загрузить, то есть модуль может быть несовместим с исполняемым файлом Emacs.

Кроме того, модуль может проверить совместимость API модуля с ожидаемым значением. Следующий пример кода предполагает, что он является частью функции emacs_module_init выше:

  emacs_env *env = runtime->get_environment (runtime);
  if (env->size < sizeof (*env))
    return 2;

Это вызывает функцию get_environment с помощью указателя, предоставленного в структуре runtime, чтобы получить указатель на среду API, C struct, который также имеет поле size , содержащее размер структуры в байтах.

Наконец, можно написать модуль, который будет работать с более старыми версиями Emacs, сравнивая размер среды, переданной Emacs, с известными размерами, например так:

  emacs_env *env = runtime->get_environment (runtime);
  if (env->size >= sizeof (struct emacs_env_26))
    emacs_version = 26;  /* Emacs 26 or later.  */
  else if (env->size >= sizeof (struct emacs_env_25))
    emacs_version = 25;
  else
    return 2; /* Unknown or unsupported version.  */

Это работает, потому что более поздние версии Emacs всегда добавляют члены в среду, но никогда не удаляют члены, поэтому размер может только увеличиваться с выпуском новых версий Emacs. Учитывая версию Emacs, модуль может использовать только те части API модуля, которые существовали в этой версии, поскольку эти части идентичны в более поздних версиях.

emacs-module.h определяет макрос препроцессора EMACS_MAJOR_VERSION. Он расширяется до целочисленной константы, которая представляет собой последнюю основную версию Emacs, поддерживаемую заголовком. См. Информация о версии. Обратите внимание, что значение EMACS_MAJOR_VERSION — константа времени компиляции и не отражает версию Emacs, которая в данный момент запущена и загрузила ваш модуль. Если вы хотите, чтобы ваш модуль был совместим с различными версиями emacs-module.h, а также различными версиями Emacs, вы можете использовать условную компиляцию на основе EMACS_MAJOR_VERSION.

Рекомендуется, чтобы модули всегда выполняли проверку совместимости, если только они не выполняют свою работу исключительно в функции инициализации и не обращаются к объектам Lisp или не используют функции Emacs, доступные через структуру среды.

Связывание функций модуля со символами Lisp

Это дает именам функций модуля имена, чтобы код Lisp мог вызывать их по этим именам. Мы описываем, как это сделать, в разделе Функции модуля ниже.

Copyright © 1990-1996, 1998-2022 Free Software Foundation, Inc.
Licensed under the GNU GPL license.
https://www.gnu.org/software/emacs/manual/html_node/elisp/Module-Initialization.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API