《Lua游戏AI开发指南 --- C/C++中调用Lua函数》
C/C++ calling Lua functions
The sandbox hooks into the Lua script through three predefined global Lua functions:
Sandbox_Initialize, Sandbox_Cleanup, and Sandbox_Update. When the sandbox is first
attached to the corresponding Lua script, the Sandbox_Initialize function is called. Each
update tick of the sandbox will also invoke the Sandbox_Update function in the Lua script.
When the sandbox is being destroyed or reloaded, the Sandbox_Cleanup function will
have an opportunity to perform any script-side cleanup.
In order for C++ to call a Lua function, the function must be retrieved from Lua and
pushed onto the stack. Function parameters are then pushed on top of the stack, followed
by a call to lua_pcall, which executes the Lua function. The lua_pcall function
specifies the number of arguments the Lua function receives, the number of expected
return values, and specifies how to handle errors:
lua.h
int lua_pcall(
lua_State* luaVM, int numberOfArguments,
int numberOfResults, int errorFunction);
For example, the Agent_Initialize Lua script function is called in the AgentUtilities
class in the following manner:
Agent.lua
function Agent_Initialize(agent)
...
end
First, the Lua function is retrieved from Lua by name and pushed onto the stack. Next, the
agent itself is pushed as the only parameter to the Agent_Initialize function. Lastly,
lua_pcall executes the function and checks whether it succeeded successfully; otherwise,
an assertion is raised by the sandbox:
AgentUtilities.cpp
void AgentUtilities::Initialize(Agent* const agent)
{
// Retrieves the lua virtual machine the agent script is
// running on. lua_State* luaVM = agent->GetLuaVM();
lua_getglobal(luaVM, "Agent_Initialize");
// Agent_Initialize accepts one parameter, an Agent.
AgentUtilities::PushAgent(luaVM, agent);
// Execute the Agent_Initialize function and check for
// success.
if (lua_pcall(luaVM, 1, 0, 0) != 0)
{
assert(false);
}
}
“C/C++中调用Lua函数”
Lua脚本的沙盒钩子是通过预先定义了三个全局的Lua函数:
1.Sandbox_Initalize。
2.Sandboxk_Cleanup。
3.Sandbox_Update。
当沙盒首次载入对应的Lua脚本,Sandbox_Initialize函数被调用。每次有所更新,沙盒调用脚本中内Sandbox_Update函数。当沙盒初建,或重新载入时,Sanbox_Cleanup函数,有机会执行任何脚本端的清理工作。
C++调用Lua函数,函数要从Lua中取得,并入栈,其参数要入栈顶,之后,用lua_pacall执行对应Lua函数。lua_pcall指定Lua函数接受的参数个数,返回值个数和容错处理。
lua.h
int lua_pcall(lua_State* luaVM, int numberOfArguments,
int numberOfResults, int errorFunction);
例如,“Agent_Initialize”脚本函数,被在“AgentUtilities”类中调用,脚本如下:
Agent.lua
function Agent_Initialize(agent)
...
end
首先,用函数名取得Lua函数,并入栈。
然后,"agen"作为唯一参数,赋给Agent_Initialize函数。
最后,用lua_pcall执行函数,并验证是否成功;
其他情况,会抛出一个沙盒的失败断言“assert(false)”。
AgentUtilities.cpp
void AgentUtilities::Initialize(Agent* const agent)
{
“取得一个agent脚本的运行虚拟机。”
// Retrieves the lua virtual machine the agent script is running on.
lua_State* luaVM = agent->GetLuaVM();
lua_getglobal(luaVM, "Agent_Initialize");
// Agent_Initialize accepts one parameter, an Agent.
“Agent_Initialize函数接收的参数,“agent”。”
AgentUtilities::PushAgent(luaVM, agent);
“执行Agent_Initialize函数,并验证是否成功。”
// Execute the Agent_Initialize function and check for success.
if (lua_pcall(luaVM, 1, 0, 0) != 0)
{
assert(false);
}
}
本文译自David Young《Lua游戏AI开发指南》一书。
翻译:糖果
PS:转载到其它平台请注明作者姓名及原文链接。
别动我代码可以不