《Lua游戏AI开发指南 --- C/C++中调用Lua函数》

3k 词

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:转载到其它平台请注明作者姓名及原文链接。

别动我代码可以不
别动我代码可以不