在Qt Creator中关联Lua与C++时遇Lua API调用错误的技术问询
解决Lua与C++交互的PANIC错误问题
兄弟,你这问题我太熟了!你现在的代码犯了两个关键错误:一是根本没加载/编译Lua脚本到状态机里,二是调用lua_call的时机不对——lua_call是用来调用栈顶的可调用对象(比如函数),但你现在栈里啥都没有,或者误把字符串当函数调用了,自然会报attempt to call a string value的panic错误。
先理清楚正确的交互步骤
Lua和C++交互的核心是操作Lua栈,正确执行脚本的流程应该是:
- 创建Lua状态机
- 打开Lua标准库(因为你用到了
io和string模块,必须打开) - 加载并编译Lua脚本(把脚本转换成Lua能执行的函数压到栈顶)
- 调用这个编译后的函数(用
lua_call) - 最后关闭状态机
针对你的场景的完整修复代码
场景1:直接执行单行脚本字符串
#include <lua.hpp> // 你的Qt函数里的代码 lua_State *state = luaL_newstate(); if (!state) { // 处理状态机创建失败的情况 return; } // 必须打开Lua标准库,否则io、string这些函数用不了 luaL_openlibs(state); // 加载并编译你的Lua脚本字符串 // 注意转义双引号,或者用单引号包裹Lua字符串 int loadResult = luaL_loadstring(state, "io.write(string.format('From Lua.'));"); if (loadResult != LUA_OK) { // 加载失败,打印错误信息 const char* errMsg = lua_tostring(state, -1); qDebug() << "Lua load error:" << errMsg; lua_close(state); return; } // 调用编译后的脚本函数(栈顶就是这个函数),0个参数,0个返回值 lua_call(state, 0, 0); // 别忘了关闭状态机 lua_close(state);
场景2:把脚本写成函数形式调用
如果你把脚本改成function main() io.write(string.format("From Lua.With P...")) end,那调用方式要调整成:
lua_State *state = luaL_newstate(); luaL_openlibs(state); // 加载包含main函数的脚本 int loadResult = luaL_loadstring(state, "function main() io.write(string.format('From Lua.With P...')) end"); if (loadResult != LUA_OK) { const char* errMsg = lua_tostring(state, -1); qDebug() << "Lua load error:" << errMsg; lua_close(state); return; } // 先执行脚本,把main函数注册到Lua全局表中 lua_call(state, 0, 0); // 从全局表中取出main函数,压到栈顶 lua_getglobal(state, "main"); // 调用main函数,0参数,0返回值 lua_call(state, 0, 0); lua_close(state);
关键知识点补充
luaL_newstate()只创建一个空的Lua环境,没有任何标准库,所以必须调用luaL_openlibs()来加载所有标准库(或者按需加载单个库,但新手直接用全量最省心)。luaL_loadstring()/luaL_loadfile()负责把脚本编译成Lua函数,加载成功后会把这个函数压到栈顶,此时才能用lua_call调用它。- 如果加载脚本失败,Lua会把错误信息压到栈顶,用
lua_tostring(state, -1)可以取出查看具体错误。
内容的提问来源于stack exchange,提问作者GKE
相关产品推荐
相关产品推荐

