省略Lua标准库的最佳方法是什么?

删除或省略Lua标准库包的最佳方法是什么? 例如,删除特定环境中的os库函数 。 有问题的项目是从源文件构建Lua,所以我可以编辑源代码,尽管如果可能的话我宁愿通过API来完成。

请参阅源代码包中的文件luaconf.h ,以便轻松访问大多数编译时配置,例如用于lua_Number的实际类型。

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

通常的做法是将该文件复制到应用程序的源代码,并根据需要进行修改,调用该副本的luaL_openlibs()代替核心版本。 如果您私下编译Lua而不链接到库中预先构建的二进制文件之一,那么您可以找到一种方法来完成符合您需求的等效方法。

当然,您也不需要编译或链接到您选择luaL_openlibs()任何库(例如os ,在loslib.c找到)的源代码。

你可能不能完全忽略的唯一库是提供诸如pairs()ipairs()pcall()tostring()类的东西的基础库,还有更多可能真的不方便的库。 当移植到其中一些存在问题的环境时,通常最好仔细查看其在lbaselib.c中的实现,并从中修剪function或重新实现它们以满足您的需求。

编辑:

在解释器中包含不同库列表的另一种方法是根本不调用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

假设您只想打开base库和package库。 在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函数的工作方式,除了它加载所有东西。

我认为该post可以回答您的问题,但有关该主题的更多信息。 请注意,你也可以“整个”整个表。

所以在你的例子中,“os”lib你可以做一个“os = nil”然后poof !​​,“os”lib / table就不见了。 在此示例之后执行“os.time()”将为现在不存在的lib /表返回错误。 此外,如果你只想在“os”中单独使用“time”方法,你可以只做“os.time = nil”。