load

Команда загружает машинный код и инициализирует новые команды.

СИНТАКСИС

      load fileName 
      load fileName packageName
      load fileName packageName interp
    

ОПИСАНИЕ

Эта команда загружает двоичный код из файла в адресное пространство приложения и вызывает инициализирующую процедуру библиотеки, чтобы включить ее в интерпретатор. Аргумент fileName есть имя файла, содержащего код. Конкретная форма кода различна на разных платформах, но чаще всего он должен быть разделяемой библиотекой, такой как .so-файлы для Solaris и .dll-файлы для Windows. Аргумент packageName есть имя библиотеки. Оно используется для определения имени инициализационной процедуры. Аргумент interp содержит имя интерпретатора (см. описание команды interp). Если аргумент interp не указан явно, то по умолчанию библиотека загружается в текущий интерпретатор.

Как только файл загружен в адресное пространство приложения, вызывается одна из двух процедур инициализации нового кода. Обычно процедура инициализации добавляет в интерпретатор новые Tcl-команды. Имя процедуры определяется исходя из имени библиотеки и из того, является интерпретатор, в который будут добавляться команды, безопасным (см. команду interp). Для обычного интерпретатора имя процедуры pkg_Init, где pkg - имя библиотеки, преобразованное следующим образом: Первая буква переведена в верхний регистр, а все остальные - в нижний. Например, если имя библиотеки Foo, то имя инициализационной процедуры должно быть Foo_Init.

Для безопасного интерпретатора имя процедуры должно быть pkg_SafeInit. Эта функция должна быть написана очень тщательно, чтобы позволить включить в безопасный интерпретатор только те команды библиотеки, которые безопасны при использовании в ненадежном коде. Дополнительная информация приведена в п. Safe.

Процедура инициализации должна соответствовать следующему прототипу:

      typedef int Tcl_PackageInitProc(Tcl_Interp  *interp);
    

Аргумент interp определяет интерпретатор, в который библиотека будет загружена. Процедура инициализации должна вернуть код TCL_OK или TCL_ERROR чтобы указать, была ли она завершена успешно. В случае ошибки она должна присвоить переменной interp->result значение указателя на сообщение об ошибке. Результат процедуры инициализации будет возвращен командой load как ее результат.

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

Команда load также поддерживает библиотеки, статически связанные с приложением, если они зарегистрированы с использованием процедуры Tcl_StaticPackage. Если аргумент fileName есть пустая строка, то необходимо указывать имя библиотеки.

Если аргумент packageName отсутствует или равен пустой строке, Tcl пытается сам сформировать имя библиотеки. На разных платформах это выполняется по-разному. На Unix-платформах обычно для этого берется последний элемент имени файла. Если первые три буквы в нем - lib, то они отбрасываются. После чего берутся все последовательные символы, которые являются буквами или символом подчеркивания. Например, если имя файла libxyz4.2.so, то в качестве имени библиотеки будет сформировано xyz, а при исполнении команды

      load bin/last.so {}
    

сформируется имя библиотеки last. Если аргумент fileName равен пустой строке, то должен быть задан аргумент packageName. Команда load в таком случае ищет сначала статически загружаемую библиотеку (то есть, библиотеку, зарегистрированную с помощью процедуры Tcl_StaticPackage) с указанным именем. Если такая будет найдена, то она используется в команде. В противном случае ищется динамически загружаемая процедура с этим именем. Если загружено несколько версий одной и той же библиотеки, то Tcl выбирает ту, которая была загружена первой.

ОШИБКИ

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