安全地从Lua栈中读取字符串

如何从 Lua 栈中安全地读取字符串值?函数 lua_tostringlua_tolstring 都可以引发 Lua 错误 (长跳转 / 奇怪类型的异常)。因此,这些函数应该在保护模式下使用 lua_pcall 调用。但我无法找到一个好的解决方案,如何在保护模式下调用这些函数并从 Lua 栈中获取字符串值到 C++。是否真的需要使用 lua_pcall 在保护模式下调用 lua_tolstring

实际上,使用 lua_pcall 似乎不好,因为我想从 Lua 栈中读取的字符串是由 lua_pcall 存储的错误消息。

点赞
用户2182618
用户2182618

你可以使用 lua_isstring 函数来检查值是否可以无误转换为字符串。

2013-03-21 09:58:46
用户1091116
用户1091116

以下是在 OpenTibia 服务器中的实现方式:

std::string LuaState::popString()
{
    size_t len;
    const char* cstr = lua_tolstring(state, -1, &len);
    std::string str(cstr, len);
    pop();
    return str;
}

来源: https://github.com/opentibia/server/blob/master/src/lua_manager.cpp

2013-03-21 10:02:44
用户107090
用户107090

在调用 lua_tostring 前先使用 lua_type:如果 lua_type 返回 LUA_TSTRING,那么你可以安全地调用 lua_tostring 获取字符串,而不会分配内存。

只有在需要将数字转为字符串时,lua_tostring 才会分配内存。

2013-03-21 11:33:56
用户2384452
用户2384452

好的,当你调用lua_pcall失败时,它会返回一个错误代码。当你成功调用lua_pcall时,你将得到零。所以,首先你应该看一下lua_pcall返回的值,然后使用lua_type获取类型,最后,使用lua_to*函数获取正确的值。

int iRet = lua_pcall(L, 0, 0, 0);
if (iRet)
{
    const char *pErrorMsg = lua_tostring(L, -1); // 错误信息
    cout<<pErrorMsg<<endl;
    lua_close(L);
    return 0;
}

int iType = lua_type(L, -1);
switch (iType)
{
    //...
    case LUA_TSTRING:
        {
            const char *pValue = lua_tostring(L, -1);
            // ...
        }
}

就这样了。 祝你好运。

2014-08-20 16:52:20