二进制字符串:预编译代码块以意外的方式结束。

我在 Ubuntu 库中使用 Lua 5.1 遇到了以下问题。但同样的问题也出现在从 _Hardy_(旧版本)到 _Precise_(相当新)的 Lua。

我想要预编译以下小小的 Lua 代码:

i = 0;

我在我的 C++ 程序中使用以下代码:

typedef struct {
    size_t *len;
    char **data;
} BS_DESCRIP;

static int hgl_lua_Writer(lua_State * /*l*/, const void *p, size_t sz, void *ud) {

    BS_DESCRIP *bd = (BS_DESCRIP *)ud;

    char *newData;

    if((newData = (char *)realloc(*(bd->data), (*(bd->len)) + sz))) {
        memcpy(newData + (*(bd->len)), p, sz);
        *(bd->data) = newData;
        *(bd->len) += sz;
    } else {
        free(newData);
        return 1;
    }

    return 0;
}

char *CompilerBase::luaCompile(char *script, size_t *scriptLen) const throw(Exception::LuaException) {

 char *byteCode = 0L;

 lua_State *l = Type::Lua::LuaTypeBase::m_luaInit.m_luaState;

 if(l) {
    size_t byteCodeLen = 0;
    int ret;

    if(!(ret = luaL_loadstring(l, script))) {
        BS_DESCRIP bd = { &byteCodeLen, &byteCode };

        lua_dump(l, hgl_lua_Writer, &bd);
        lua_pop(l, 1);

        logDebug("Rechecking pre-compiled Lua string...");
        ret = luaL_loadstring(l, byteCode);
    }

    if(ret) {
        if(ret == LUA_ERRSYNTAX) {
            throw Exception::LuaException(lua_tostring(l, -1));
        } else if(ret == LUA_ERRMEM) {
            throw Exception::LuaException("Lua memory allocation error");
        } else {
            throw Exception::LuaException("Lua unknown error");
        }
    } else {
        *scriptLen = byteCodeLen;
    }

 } else {
    throw Exception::LuaException("Lua hasn't been initialized");
 }

 return byteCode;
}

任何包括上述最小代码的 Lua 代码都会在 "Rechecking" 时失败,显示以下错误:

binary string: unexpected end in precompiled chunk

但我找不到错误。

我的错误在哪?我毫无头绪 :-(

点赞
用户2198692
用户2198692

如我所承诺的那样,这是我用来转储字节码的 Lua writer 函数的版本:

int lua_MemoryWriter(lua_State *lua, const void *p, size_t sz, void *ud)
{
    MemStreamBuf *buf = (MemStreamBuf*)ud;
    if (buf->sputn((const char*)p, sz) == sz)
        return 0;
    else
        return 1;
}

其中 MemStreamBuf 是我实现的一个简单的 std::streambuf,用于将内容流向内存缓冲区。

但是你也可以用 std::string 来实现同样的功能:

int lua_MemoryWriter(lua_State *lua, const void *p, size_t sz, void *ud)
{
      std::string *buf = (std::string*)ud;
      buf->append((const char*)p, sz);
      return 0;
}

当然,如果在这时抛出了任何异常,这里并不处理。

在这里有一个重要的编辑:

脸掌!

字节码中包含了 0。你需要调用 luaL_loadbuffer 并给出实际的缓冲区大小,以考虑到字符串中的空字符。

已经到了周末,思路比较缓慢,请多谅解 ;)!

2013-05-10 12:24:34