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

时间:2009-06-08 18:09:15

标签: c lua

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

3 个答案:

答案 0 :(得分:29)

请参阅源代码包中的文件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()不是强制性的。相反,只显示您想要的库。

参考手册的

Chapter 5谈到了这一点:

  

要访问这些库,可以使用   C主机程序应该调用   luaL_openlibs功能,打开   所有标准库。或者,   它可以单独打开它们   呼叫luaopen_base(基本的   图书馆),luaopen_package(对于   包库),luaopen_string(for   字符串库),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

答案 1 :(得分:10)

假设您只想打开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函数的工作方式,除了它加载所有内容。

答案 2 :(得分:3)

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

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