一、Lua的编译和使用
编译方法网上一大堆,但我最终编译了4个版本,分别是:/MT的DEBUG版本、Release版本、/MD的Debug版本和Release版本。并且在工程中加入下面的代码:
#pragma message( "Linker with lua lib...") // 只是一条信息而已
#ifdef _DEBUG // 如果是Debug版本
# ifdef _DLL // 如果宿主程序使用/MD
# pragma comment( lib, "Lua5.2.2\\lib\\lua5.2.2_MD_d.lib")
# else
# pragma comment( lib, "Lua5.2.2\\lib\\lua5.2.2_MT_d.lib")
# endif
#else
# ifdef _DLL
# pragma comment( lib, "Lua5.2.2\\lib\\lua5.2.2_MD_r.lib")
# else
# pragma comment( lib, "Lua5.2.2\\lib\\lua5.2.2_MT_r.lib")
# endif
#endif
这样,就能自动加载对应的版本了。
二、Lua与C的交互
● 记住,lua通过那个所谓的工作栈来和C交互,因此,最重要的,是一定要平衡栈。
● 关于lua_pcall
1、先得将要调用的lua函数压入栈中,方法是lua_getglobal,但脚本中可能不存在这个函数,也可能存在一个同名的其他类型的变量但不是函数,因此,调用完lua_getglobal之后,应当使用lua_isfunction检查一下它是不是一个函数。如果不是,除了提示一下错误信息之外,还要把那个已经入栈了的东西出栈(lua_pop)。
2、然后就是压入函数参数了,有几个参数就压几个,同时在调用lua_pcall时指明正确的参数个数。无论lua_pcall是不是调用成功,它都会将参数和函数出栈,因此,不需要在调用后pop那些参数和函数,但是,如果调用失败了,lua会在栈里压入一个错误信息,这个错误信息用完了之后,是要用lua_pop进行弹出的。
lua_getglobal( g_pLua, "LuaFunctionName" );
if( lua_isfunction( g_pLua, -1 ))
{
lua_pushinteger( g_pLua, nParam1 );
lua_pushinteger( g_pLua, nParam2 ); // 压入两个参数
if( lua_pcall( g_pLua, 2, 1, 0 ) == 0 ) // 指明该函数有2个参数,并且返回1个结果
{
//调用成功了
nResult = lua_tointeger( g_pLua, -1 ); // 使用函数结果
lua_pop( g_pLua, 1 ); // 弹出结果,平衡栈。
}
else
{
//调用失败了,显示错误信息
error( "调用%s函数失败,信息如下:%s", lpszLuaFunction, lua_tostring( g_pLua, -1 );
lua_pop( g_pLua, 1 ); // 这里是弹出错误信息。
}
}
else
{
error( "脚本中不存在%s函数", lpszLuaFunction );
lua_pop( g_pLua, 1 ); // 将不是函数的这个东东出栈。
}三、表的操作
1、lua_newtable创建一个表,并且,将表入栈。
2、lua_push** 将表的key入栈。
3、lua_push** 将表的value入栈。
3、lua_settable( pLua, -3 )。-3是指表在栈中的位置。该函数操作完成后,会将Key和value出栈!栈恢复到1的状态。
4、如果所创建的表是为了在C API中返回,则此时直接return 1即可,因为表还在栈中。
5、还可以调用lua_setglobal将表设置到Lua全局中,setglobal会清理栈(newtable所创建的表)。
本文详细介绍了Lua的编译及使用方法,包括如何根据不同的编译选项选择合适的库文件;深入探讨了Lua与C语言的交互机制,重点讲解了lua_pcall的正确使用方式以确保栈的平衡;最后还介绍了Lua中表的基本操作。
1174

被折叠的 条评论
为什么被折叠?



