luaL_dofile在已知良好的字节码上失败,可以使用未编译的版本
luaL_dofile fails on known-good bytecode, works with uncompiled version
我已经组装了一个非常简单的Lua引擎,但它似乎拒绝了在Lua控制台中工作的字节码。未编译的版本在引擎中工作。我是不是用错了luac?
我使用给定的命令进行编译,并以"的形式运行/a.out'.
res/default.loa:
print("Setting up world structure.")
luac命令:
luac -o res/default.lux res/default.lua
MWE:
#define SCRIPTDIR "res/"
#define THROW_IF_NONZERO(x,m) if((x)!=0) throw std::runtime_error(m);
#define THROW_IF_ZERO(x,m) if((x)==0) throw std::runtime_error(m);
extern "C" {
#include "lua.h"
#include "lauxlib.h"
#include "lualib.h"
}
#include "sys/stat.h"
#include <string>
#include <system_error>
#include <iostream>
using std::string;
class Entity {
private:
lua_State *m_lua;
public:
Entity() : Entity(nullptr) { }
Entity(lua_State *lua) : m_lua{lua} { }
virtual ~Entity() { }
void load_and_run(string);
};
class WorldEntity : public Entity {
public:
WorldEntity(lua_State *lua) : Entity(lua) {
luaL_openlibs(lua);
}
~WorldEntity() { }
};
int main() {
lua_State *lua{nullptr};
try {
lua = luaL_newstate();
WorldEntity eWorld{lua};
eWorld.load_and_run("default"); // load default.lua/lux
} catch(std::exception &e) {
if (lua != nullptr) {
lua_close(lua);
}
std::cout << "Error: " << e.what() << std::endl;
}
return 0;
}
void Entity::load_and_run(string filename) {
THROW_IF_ZERO(m_lua, "Lua not started.");
filename = SCRIPTDIR + filename + ".lux";
struct stat sb;
int rc = stat(filename.c_str(), &sb);
if (rc == -1) {
filename.pop_back();
filename += "a";
rc = stat(filename.c_str(), &sb);
THROW_IF_NONZERO(rc, "File not found!");
}
std::cout << "File: " << filename << std::endl;
// Currently won't run compiled Lua scripts, not sure why.
rc = luaL_dofile(m_lua, filename.c_str());
THROW_IF_NONZERO(rc, "Could not load lua file.");
}
编译命令:
gcc src/bug001mwe.cpp -std=c++14 -llua -lstdc++
脚本的正确输出:
File: res/default.lua
Setting up world structure.
字节码输出错误:
File: res/default.lux
Error: Could not load lua file.
两个文件,从lua控制台输出:
Setting up world structure.
让我困惑的是,它在lua控制台中工作,但在我的程序中不工作。在调用luaL_dofile之后,我添加了一个对lua_tostring的调用,如下所示:
rc = luaL_dofile(m_lua, filename.c_str());
std::ostringstream ostr;
ostr << "Could not load lua file. ";
ostr << lua_tostring(m_lua, -1);
THROW_IF_NONZERO(rc, ostr.str());
错误字符串变为:
Error: Could not load lua file. res/default.lux: version mismatch in precompiled chunk
怎么了?
长话短说,由于一些不相关的东西中的包依赖关系过时,我安装了以前版本的Lua。旧的luac拦截了luac命令,并编译为有效但不兼容的字节码。卸载了我并不真正需要的无关软件包,现在一切都正常了。
这个故事的寓意是:总是检查Lua堆栈上的错误字符串,它(可能(会告诉你出了什么问题。
相关文章:
- 是否可以使C++类成为Objc类的委托
- 是否可以使一个类成为两个不同层次结构的子类?
- 是否有编译器标志可以使较新的 gcc 版本像旧版本一样构建
- C 可以使destuructor不称为班级成员和基类攻击方的灾难
- 可以使未命名的结构静态
- 是否可以使整数仅收到一个单个数字而不是两个接收输入
- C++:有哪些常规方法可以使代码更有效地用于大数字
- 是否可以使 std 容器使用默认运算符为新?
- LD_BIND_NOW可以使可执行文件运行得更慢?
- 是否可以使头文件使文本居中?- 在控制台中
- 有什么方法可以使核心忙碌等待
- 有没有一种技术可以使虚函数在所有派生类中强制重写?
- 有没有一种方法可以使全局函数/静态成员函数一次可呼出
- 是否有一种方法可以使此C 14递归模板在C 17中短
- 编写一个可以使二维数组平坦的函数
- 有哪些优化技巧可以使我的代码运行得更快
- 有没有更好的方法可以使此代码线程安全?线程局部静态似乎是一个生硬的工具
- 如果必须在同一向量上写入线程,是否可以使用线程
- 对于具有两个模板化变量的模板化类,是否可以使一个 var 引用另一个 var
- 内联失败:可以在链接时覆盖函数体