编译lua代码,存储字节码然后加载并执行

Posted

技术标签:

【中文标题】编译lua代码,存储字节码然后加载并执行【英文标题】:Compile lua code, store bytecode then load and execute it 【发布时间】:2012-02-14 17:18:10 【问题描述】:

我正在尝试编译一个调用一些导出函数的 lua 脚本,将生成的字节码保存到一个文件中,然后加载这个字节码并执行它,但我还没有找到任何关于如何执行此操作的示例。有没有关于如何做到这一点的例子?我该怎么做?

编辑:我正在使用 Lua + Luabind (C++)

【问题讨论】:

【参考方案1】:

这一切都很简单。

首先,您加载 Lua 脚本而不执行它。是否已将 Lua 状态与导出的函数连接起来并不重要;你所做的只是编译脚本文件。

您可以使用luaL_loadfile,它使用C 标准库函数从磁盘读取文件并将其加载到lua_State。或者,您可以自己将文件加载到字符串中,然后使用luaL_loadstring 将其加载到lua_State

这两个函数都会根据the documentation for lua_load 发出返回值和编译器错误。

如果编译成功,lua_State 现在将已编译的 Lua 块作为 Lua 函数放在堆栈顶部。要获取编译后的二进制文件,您必须使用lua_dump 函数。这相当复杂,因为它使用回调接口向您传递数据。见the documentation for details。

在这个过程之后,你就有了编译好的 Lua 字节码。将其放入您选择的文件中。请记住:将其写为二进制,而不是文本翻译。

当需要加载字节码时,您需要做的就是... 与您之前所做的完全相同。嗯,差不多。 Lua 具有启发式方法来检测给定的“字符串”是 Lua 源字符串或字节码。所以是的,您可以像以前一样使用luaL_loadfile 加载字节码。

不同之处在于您不能将luaL_loadstring 与字节码一起使用。该函数需要一个以 NULL 结尾的字符串,这很糟糕。字节码中可以嵌入 NULL 字符,这会搞砸一切。所以如果你想自己做文件IO(因为你使用的是特殊的文件系统什么的),你必须直接使用lua_load(或者luaL_loadbuffer)。它还使用像lua_dump 这样的回调接口。所以read up on how to use it。

【讨论】:

希望有更多这样合理的答案! 很好的答案,这正是我的想法,但我只是不知道该使用什么。我会尝试一下。现在告诉我,将这样的内容(清晰而客观)放在常见问题解答甚至文档中有多难?谢谢! @WoLfulus:如果您在 Google 上搜索“Lua 加载字节码”,very first link 会告诉您您需要知道的一切。所以我认为没有必要为此提供常见问题解答。并且应用程序luac 已经可以将 Lua 脚本预编译为字节码,因此您甚至不需要程序来完成它。所以说真的,不需要FAQ。正确使用 Google。 @NicolBolas 实际上,这个 SO 问题现在是“Lua 加载字节码”的最高 google 结果,所以我认为常见问题解答请求是有效的。 实际上luaL_loadstring 在加载存储的字节码时不会(总是)正常工作,因为它使用strlen(s) 来确定要加载的输入缓冲区的长度(github.com/LuaDist/lua/blob/…),并且作为字节码可以包含空字符,它会给出错误的长度。您需要做的是调用luaL_loadbuffer 并将字节码数组及其大小传递给它。除此之外,答案是正确的。

以上是关于编译lua代码,存储字节码然后加载并执行的主要内容,如果未能解决你的问题,请参考以下文章

深入理解Lua虚拟机

深入理解 Lua 虚拟机

JAVA中的字节码是啥?

Android 逆向类加载器 ClassLoader ( 使用 DexClassLoader 动态加载字节码文件 | 拷贝 DEX 文件到内置存储 | 加载并执行 DEX 字节码文件 )

Java字节码的执行是由啥完成的?

luajit与NYI