省略 Lua 标准库的最佳方法? [英] Best way to omit Lua standard libraries?

查看:19
本文介绍了省略 Lua 标准库的最佳方法?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

解决方案

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

通过调用luaL_openlibs() 加载的核心库列表,请参见源工具包中的文件linit.c.

通常的做法是将该文件复制到您的应用程序的源代码中,并对其进行修改以满足您的需要,调用该副本的 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(用于 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();如果 (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);}返回 L;}

成功时返回新的lua_State,失败时返回NULL.

What is the best way to remove or omit a Lua standard library package? For example remove the os library functions in a particular environment. The project in question is building Lua from the source files so I can edit the source, although I would rather do it through the API if possible.

解决方案

See the file luaconf.h in the source kit for easy access to most compile-time configuration such as the actual type used for lua_Number.

See the file linit.c in the source kit for the list of core libraries that are loaded by calling luaL_openlibs().

Common practice is to copy that file to your application's source, and modify it to suit your needs, calling that copy's luaL_openlibs() in place of the core version. If you are compiling Lua privately and not linking to one of the pre-built binaries of the library, then you can find a method to do the equivalent that suits your needs.

Of course, you also don't need to compile or link to the sources for any library (such as os, found in loslib.c) that you choose to leave out of luaL_openlibs().

The only library that you probably can't leave out completely is the base library that provides things like pairs(), ipairs(), pcall(), tostring(), and lots more that can be really inconvenient to do without. When porting to an environment where some of these are problematic, it is usually a good idea to look closely at its implementation in lbaselib.c and either trim features from it or reimplement them to suit your needs.

Edit:

Another approach to including a different list of libraries in the interpreter is to not call luaL_openlibs() at all. Although provided as a convenience, like all of the auxiliary library, luaL_openlibs() is not mandatory. Instead, explicitly open just the libraries you want.

Chapter 5 of the reference manual talks about this:

To have access to these libraries, the C host program should call the luaL_openlibs function, which opens all standard libraries. Alternatively, it can open them individually by calling luaopen_base (for the basic library), luaopen_package (for the package library), luaopen_string (for the string library), luaopen_table (for the table library), luaopen_math (for the mathematical library), luaopen_io (for the I/O library), luaopen_os (for the Operating System library), and luaopen_debug (for the debug library). These functions are declared in lualib.h and should not be called directly: you must call them like any other Lua C function, e.g., by using lua_call.

That last sentence is occasionally the source of trouble, since older versions of Lua did not have that restriction. Each of the individual module's luaopen_xxx() functions follows the same protocol used by the require function. It should be passed a single argument: a string containing the name by which the module is known. The exception is the base module, which is passed an empty string because it has no actual name.

Here's a function that creates a new Lua state and opens only the base and package libraries:

#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;
}

It returns the new lua_State on success, or NULL on failure.

这篇关于省略 Lua 标准库的最佳方法?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆