最佳方法如何省略Lua标准库?

什么是删除或省略Lua标准库包的最佳方法?例如,在特定环境中删除 os库函数 。相关项目正在从源文件构建Lua,因此我可以编辑源文件,虽然如果可能的话,我宁愿通过API来完成。

原文链接 https://stackoverflow.com/questions/966162

点赞
stackoverflow用户68204
stackoverflow用户68204

查看源码包中的文件 luaconf.h,以轻松访问大部分编译时配置,例如 lua_Number 所用的实际类型。

查看源码包中的文件 linit.c,以获取通过调用 luaL_openlibs() 加载的核心库列表。

通常的做法是将该文件复制到应用程序的源代码中,并根据需要进行修改,在该副本中调用其 luaL_openlibs() 代替核心版本。如果您正在私有地编译 Lua 并且没有链接到库的预编译二进制文件之一,则可以找到一种适合您需求的等效方法。

当然,您也不需要编译或链接到任何库的源代码(例如在 loslib.c 中找到的 os),它们是您选择在 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(用于 I/O 库)、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

2009-06-08 20:18:52
stackoverflow用户88888888
stackoverflow用户88888888

我认为该文章回答了你的问题,但是还需要一些相关的信息。

请注意,您也可以完全“nil”整个表。

因此,在您的示例中,“os”库您可以执行“os = nil”,然后瞬间,该“os”库/表就消失了。在执行此示例之后执行“os.time()”将返回一个错误,因为该库/表不存在。 此外,如果您只想在“os”中单独取消“time”方法,您可以执行“os.time = nil”。

2009-06-28 13:40:51
stackoverflow用户1205758
stackoverflow用户1205758

假设你只想打开 basepackage 库。在 Lua 5.2 中,最简洁的方法是:

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

这是 linit.c 中的 luaL_openlibs 函数的工作方式,除了它加载了所有内容。

2013-03-01 14:40:55