Лучший способ опустить стандартные библиотеки Lua?

Каков наилучший способ удалить или опустить стандартный пакет Lua? Например, удалите функции os library в конкретной среде. Этот проект создает Lua из исходных файлов, поэтому я может редактировать исходный код, хотя я бы скорее сделал это через API, если это возможно.

Ответы

Ответ 1

Смотрите файл luaconf.h в исходном наборе, чтобы получить легкий доступ к большинству конфигураций времени компиляции, таких как фактический тип, используемый для lua_Number.

См. файл linit.c в исходном наборе для списка основных библиотек, загружаемых вызовом luaL_openlibs().

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

Конечно, вам также не нужно компилировать или ссылаться на источники для любой библиотеки (например, os, найденной в loslib.c), которую вы решили оставить из luaL_openlibs().

Единственная библиотека, которую вы, возможно, не можете полностью исключить, это базовая библиотека, которая предоставляет такие вещи, как pairs(), ipairs(), pcall(), tostring() и многое другое, что может быть неудобно делать без, При переносе в среду, где некоторые из этих проблем проблематичны, обычно рекомендуется внимательно изучить ее реализацию в lbaselib.c и либо обрезать функции из нее, либо переопределить их в соответствии с вашими потребностями.

Изменить:

Другой подход включить другой список библиотек в интерпретаторе - вообще не вызывать luaL_openlibs(). Хотя это и удобно, как и вся вспомогательная библиотека, luaL_openlibs() не является обязательным. Вместо этого явно открывайте нужные библиотеки.

Глава 5 справочного руководства говорит об этом:

Чтобы иметь доступ к этим библиотекам, C хост-программе следует вызвать luaL_openlibs, которая открывается все стандартные библиотеки. С другой стороны, он может открыть их отдельно вызов luaopen_base (для основного библиотека), luaopen_package (для библиотека пакетов), luaopen_string (для строка библиотеки), luaopen_table(для библиотеки таблиц), luaopen_math(для математической библиотеки), luaopen_io (для библиотеки ввода/вывода), luaopen_os (для операционной системы библиотека) и luaopen_debug (для debug library). Эти функции объявлено в lualib.h и не должно быть вызываемые напрямую: вы должны их назвать как и любая другая функция Lua C, например, используя lua_call.

Последнее предложение иногда является источником проблем, поскольку более старые версии Lua не имеют такого ограничения. Каждая из функций отдельного модуля luaopen_xxx() следует тому же протоколу, который используется функцией require. Ему должен быть передан один аргумент: строка, содержащая имя, с помощью которого модуль известен. Исключением является базовый модуль, которому передается пустая строка, поскольку он не имеет фактического имени.

Здесь функция, которая создает новое состояние Lua и открывает только базовые и пакетные библиотеки:

#include "lua.h"
#include "lualib.h"
#include "lauxlib.h"

lua_State *CreateBasicLua() {
    lua_State *L;

    L = luaL_newstate();
    if (L) {
        lua_pushcfunction(L, luaopen_base);
        lua_pushstring(L, "");
        lua_call(L, 1, 0);
        lua_pushcfunction(L, luaopen_package);
        lua_pushstring(L, LUA_LOADLIBNAME);
        lua_call(L, 1, 0);
    }
    return L;
}

Он возвращает новый lua_State при успешном завершении или NULL при сбое.

Ответ 2

Предположим, вы только хотите открыть библиотеки base и package. В Lua 5.2 наиболее кратким способом является

luaL_requiref(L, "_G", luaopen_base, 1);
luaL_requiref(L, "package", luaopen_package, 1);
lua_pop(L, 2);

Вот как работает функция luaL_openlibs в linit.c, за исключением того, что она загружает все.

Ответ 3

Я думаю, что сообщение отвечает на ваш вопрос, но немного больше информации по этому вопросу. Имейте в виду, что вы также можете просто "нуль" целых таблиц.

Итак, в вашем примере "os" lib вы можете сделать "os = nil", затем poof!, "os" lib/table ушел. Выполнение "os.time()" после этого примера вернет ошибку для несуществующей библиотеки lib/table. Кроме того, если вы просто хотите использовать метод "времени" в "os" , вы можете просто "os.time = nil".