从字符串中执行 Lua 函数
2016-5-12 2:19:11
收藏:0
阅读:75
评论:2
我需要执行一个 Lua 函数,该函数是 XML 文件的一部分。我将解析 XML 并将整个函数作为字符串加载。
当我尝试执行 lua_pcall 时,它给出 attempt to call a nil value 错误。但是,当我尝试删除函数部分并仅使用内部逻辑时,它对我有效。我需要理解是否需要执行任何其他步骤以执行为函数。
初始化:
/* Lua 解释器 */
lua_State *luaState;
// 初始化 Lua
luaState = luaL_newstate();
lua_register(luaState, "getValue", get_value);
lua_register(luaState, "setValue", set_value);
// 载入 Lua 基础库
luaL_openlibs(luaState);
_工作流程_: XML
-- 由该算法执行的 Lua 脚本
-- 使用下列 API 调用来获取和设置功能块数据
-- local IN1 = getValue("IN1")
-- setValue("OUT1", value)
setValue("RequestAccepted", "true");
-- lua 脚本
C++ 代码:
TAlgoTable::iterator iter = algoTable.find("RequestAccepted");
if (luaL_dostring(luaState, iter->second.c_str()))
{
printf("Failure at Algorithm : 'RequestAccepted' Reason : %s", lua_tostring(luaState, -1));
}
不工作:
-- 由该算法执行的 Lua 脚本
function RequestAccepted()
-- 使用下列 API 调用来获取和设置功能块数据
-- local IN1 = getValue("IN1")
-- setValue("OUT1", value)
setValue("RequestAccepted", "true");
end -- lua 脚本
C++ 代码:
lua_getglobal(luaState, "RequestAccepted"); // 要调用的函数
if (lua_pcall(luaState, 0, 0, 0)) {
printf("Failure at Algorithm : 'RequestAccepted' Reason : %s", lua_tostring(luaState, -1));
}
点赞
用户6301420
在我的一个项目中,我是通过创建一个 Lua 引用来实现的(请原谅格式,复制粘贴):
int SParamSchemaNode::parseScript(lua_State* L,
const char* arglist,
const char* body)
{
std::ostringstream bufToParse;
// 保存旧栈顶,这样如果第二个 try 成功,我们就可以清理第一个 try 的错误
int oldStackTop = lua_gettop(L);
bufToParse << "return function(" << arglist << ") return ("
<< body << ") end";
if (luaL_dostring(L, bufToParse.str().c_str()))
{
int parseError1_pos = lua_gettop(L);
bufToParse.str(std::string()); // 重置 bufToParse 字符串为空
bufToParse << "return function(" << arglist << ") "
<< body << " end";
if (luaL_dostring(L, bufToParse.str().c_str()))
{
// 由于错误消息包括我们正在尝试解析的脚本,因此结果具有无限长度;因此使用另一个 ostringstream 来保存错误消息
std::ostringstream errmsg;
errmsg << "Errors parsing the following script:" << std::endl;
errmsg << body << std::endl << std::endl;
errmsg << "Parser error when interpreting as an expression:" << std::endl;
errmsg << lua_tostring(L, parseError1_pos) << std::endl << std::endl;
errmsg << "Parser error when interpreting as a function body:" << std::endl;
errmsg << lua_tostring(L, -1);
ERROR_ReportError(errmsg.str().c_str());
}
}
if (DEBUG)
{
std::cout << "Successfully loaded chunk: " << bufToParse.str() << std::endl;
}
int ref = luaL_ref(L, LUA_REGISTRYINDEX);
lua_settop(L, oldStackTop);
return ref;
}
然后我将其存储在(例如)SParameterDefinition::m_applicableScriptRef 成员中,并使用以下代码调用:
bool SParameterDefinition::isApplicable(SAbstractComponent* cmpt, int index)
{
if (m_applicableScriptRef == LUA_NOREF)
{
return true;
}
lua_State* L = schema()->luaState();
// 从注册表中获取要调用的函数
lua_rawgeti(L, LUA_REGISTRYINDEX, m_applicableScriptRef);
// 推动 "cmpt" 参数
SWIG_UC_push_SAbstractComponent(L, cmpt);
int nargs = 1;
if (m_isInstanced)
{
lua_pushnumber(L, index);
nargs++;
}
// 函数的受保护调用(nargs 个参数,1 个结果,没有特殊的错误处理程序函数)
int script_result = lua_pcall(L, nargs, 1, 0);
if (script_result != 0)
{
std::ostringstream errmsgBuf;
errmsgBuf << "Error while calling applicable script for "
<< "parameter " << m_name << ":\n";
errmsgBuf << lua_tostring(L, -1);
ERROR_ReportError(errmsgBuf.str().c_str());
}
if (! lua_isboolean(L, -1))
{
report_type_error("Applicable",
m_name.c_str(), "boolean",
luaL_typename(L, -1));
}
bool result = (lua_toboolean(L, -1) != 0);
lua_pop(L, 1);
return result;
}
您可能不需要这里的全部复杂性,但基本要点是将函数主体包装在 return function() ... end 中,使用 luaL_dostring 对其进行评估,然后使用 luaL_ref(L, LUA_REGISTRYINDEX) 存储该脚本的结果。
2016-05-12 02:44:25
评论区的留言会收到邮件通知哦~
推荐文章
- 如何将两个不同的lua文件合成一个 东西有点长 大佬请耐心看完 我是小白研究几天了都没搞定
- 如何在roblox studio中1:1导入真实世界的地形?
- 求解,lua_resume的第二次调用继续执行协程问题。
- 【上海普陀区】内向猫网络招募【Skynet游戏框架Lua后端程序员】
- SF爱好求教:如何用lua实现游戏内调用数据库函数实现账号密码注册?
- Lua实现网站后台开发
- LUA错误显式返回,社区常见的规约是怎么样的
- lua5.3下载库失败
- 请问如何实现文本框内容和某个网页搜索框内容连接,并把网页输出来的结果反馈到另外一个文本框上
- lua lanes多线程使用
- 一个kv数据库
- openresty 有没有比较轻量的 docker 镜像
- 想问一下,有大佬用过luacurl吗
- 在Lua执行过程中使用Load函数出现问题
- 为什么 neovim 里没有显示一些特殊字符?
- Lua比较两个表的值(不考虑键的顺序)
- 有个lua简单的项目,外包,有意者加微信 liuheng600456详谈,最好在成都
- 如何在 Visual Studio 2022 中运行 Lua 代码?
- addEventListener 返回 nil Lua
- Lua中获取用户配置主目录的跨平台方法
我发现并理解了我需要将函数加载到缓冲区中。 以下链接帮助我解决了问题 http://gouthamanbalaraman.com/blog/minimal-example-lua-function-cpp.html