Лучший способ опустить стандартные библиотеки Lua? - PullRequest
13 голосов
/ 08 июня 2009

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

Ответы [ 3 ]

29 голосов
/ 09 июня 2009

См. Файл 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 (для библиотека отладки). Эти функции объявлено в 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 в случае ошибки.

10 голосов
/ 01 марта 2013

Допустим, вы хотите открыть только библиотеки 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 голосов
/ 28 июня 2009

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...