Cocos2d-x中Lua与C++通信
参考文章地址:http://www.himigame.com/lua-game/1343.html
几个Lua中的API介绍
int luaL_dofile (lua_State *L, const char *filename) :
加载并运行指定文件,没有错误返回0
void lua_settop (lua_State *L, int index):
参数允许传入任何可接受的索引以及 0 。 它将把堆栈的栈顶设为这个索引。 如果新的栈顶比原来的大,超出部分的新元素将被填为 nil 。 如果 index 为 0 ,把栈上所有元素移除。
void lua_getglobal (lua_State *L, const char *name):
把全局变量 name 里的值压入堆栈。
void lua_pop (lua_State *L, int n):
从堆栈中弹出 n 个元素。相当于清除!
void lua_pushstring (lua_State *L, const char *s):
把指针 s 指向的以零结尾的字符串压栈。 Lua 对这个字符串做一次内存拷贝(或是复用一个拷贝), 因此 s 处的内存在函数返回后,可以释放掉或是重用于其它用途。 字符串中不能包含有零字符;第一个碰到的零字符会认为是字符串的结束。
更多的API请参考:http://www.codingnow.com/2000/download/lua_manual.html
C++声明
#ifndef __LUA_TEST_H__
#define __LUA_TEST_H__
#include "cocos2d.h"
//引入lua库,由于lua是用C语言实现的,所以需要添加extern "C"
EXTERN_C{
#include "lua.h"
#include "lualib.h"
#include "lauxlib.h"
}
#include "CCLuaEngine.h"
class LuaTest
{
public:
/********* 获取Lua中的全局字符串 *********/
const char* getLuaString(const char* script,const char* varName);
/********* 获取Lua中全局table的字符串 *********/
const char* getLuaString4Table(const char* script,const char* table, const char* varName);
/********* 打印Lua中全局table的元素 *********/
void printLuaTable(const char* script, const char* table);
/********* C++调用Lua中的全局函数 *********/
int callLuaAdd(const char* script, int a,int b);
/********* Lua调用C++的静态函数 *********/
void luaCallCppFunctionTest();
/** 获取文件全路径 **/
static const char* getFullPath(const char* file);
/** C++静态函数需要注册才能被Lua调用,而且参数为一个lua_State*,返回值为int **/
static int cppAdd(lua_State* L);
};
#endif
C++实现
#include "LuaTest.h"
USING_NS_CC;
/********* 获取Lua中的全局字符串 *********/
const char* LuaTest::getLuaString(const char* script,const char* varName){
lua_State* L = CCLuaEngine::defaultEngine()->getLuaStack()->getLuaState();
//加载并运行脚本
int isOpen = luaL_dofile(L, LuaTest::getFullPath(script));
if (isOpen != 0)
{
CCLOG("execute script %s failure. error_code=%d error_msg=%s",script,isOpen,lua_tostring(L,-1));
return NULL;
}
//Lua中的全局字符串varName入栈
lua_getglobal(L,varName);
//判断栈顶元素是否字符串
if(lua_isstring(L,-1)){
//返回栈顶字符串
return lua_tostring(L,-1);
}
return NULL;
}
/********* 获取Lua中全局table的字符串 *********/
const char* LuaTest::getLuaString4Table(const char* script,const char* table, const char* varName){
lua_State* L = CCLuaEngine::defaultEngine()->getLuaStack()->getLuaState();
//加载并运行脚本
int isOpen = luaL_dofile(L,LuaTest::getFullPath(script));
if (isOpen != 0)
{
CCLOG("execute script %s failure. error_code=%d error_msg=%s",script,isOpen,lua_tostring(L,-1));
return NULL;
}
//对Lua中的table执行压栈
lua_getglobal(L,table);
//如果栈顶元素是一个table
if(lua_istable(L,-1)){
//key入栈
lua_pushstring(L,varName);
//当前栈顶元素为varName,索引为-1;table在varName下面,索引为-2
//获取table中varName元素的值,第二个参数为当前tabele在栈中的索引位置
lua_gettable(L,-2);
//当前栈顶元素为table中varName元素的值
const char* value = lua_tostring(L,-1);
//从栈中弹出一个元素
lua_pop(L,1);
return value;
}
return NULL;
}
/********* 打印Lua中全局table的元素 *********/
void LuaTest::printLuaTable(const char* script, const char* table){
lua_State* L = CCLuaEngine::defaultEngine()->getLuaStack()->getLuaState();
//加载并运行脚本
int isOpen = luaL_dofile(L,LuaTest::getFullPath(script));
if (isOpen != 0)
{
CCLOG("execute script %s failure. error_code=%d error_msg=%s",script,isOpen,lua_tostring(L,-1));
return;
}
//table入栈
lua_getglobal(L,table);
//获取栈顶索引(该方法相当于获取栈中元素的个数,因为栈的索引是从1开始往上升的)
int top = lua_gettop(L);
//由于lua_next会先对栈执行一次弹出操作,然后再从table中获取一对key-value入栈,所以先放一个nil在栈顶
lua_pushnil(L);
if (lua_istable(L,top))
{
CCLOG("iterator is start.. table=%s",table);
//迭代table
while (lua_next(L,top)) //key出栈,key-value入栈(如果table中还有元素)
{
//获取key
const char* key = lua_tostring(L,-2);
//获取value
const char* value = lua_tostring(L,-1);
CCLOG("%s - %s",key,value);
lua_pop(L,1);//value出栈
}
CCLOG("iterator is end..");
lua_pop(L,1);//key出栈
}
}
/********* C++调用Lua中的全局函数 *********/
int LuaTest::callLuaAdd(const char* script, int a,int b){
lua_State* L = CCLuaEngine::defaultEngine()->getLuaStack()->getLuaState();
//lua函数入栈
lua_getglobal(L,"add");
if (lua_isfunction(L,-1))
{
//参数入栈
lua_pushnumber(L,a);
lua_pushnumber(L,b);
//调用lua函数:第二个参数是函数的参数个数,第三个参数是函数的返回值个数
lua_call(L,2,1);
//获取返回值
if (lua_isnumber(L,-1))
{
return lua_tonumber(L,-1);
}
}
return NULL;
}
/********* Lua调用C++的静态函数 *********/
void LuaTest::luaCallCppFunctionTest(){
lua_State* L = CCLuaEngine::defaultEngine()->getLuaStack()->getLuaState();
//注册C++函数(函数必须是静态的)
lua_register(L,"cppAdd",LuaTest::cppAdd);
//加载并运行lua脚本
luaL_dofile(L,LuaTest::getFullPath("script/testCallCppFun.lua"));
}
int add(int a, int b){
return a+b;
}
/** C++静态函数 **/
int LuaTest::cppAdd(lua_State* L){
//从栈中获取参数
int a = luaL_checknumber(L,-1);
int b = luaL_checknumber(L,-2);
//调用C++中的add函数
int result = add(a,b);
//对结果入栈
lua_pushnumber(L,result);
return 1;//返回值个数
}
const char* LuaTest::getFullPath(const char* file){
//return CCFileUtils::sharedFileUtils()->fullPathForFilename(file).c_str();
std::string filePath = CCFileUtils::sharedFileUtils()->fullPathForFilename(file).c_str();
CCLOG(filePath.c_str());
return file;
}Lua代码
test.lua的代码:
--Lua中的字符串
luaStr = "this is a string form lua"
luaTable = { name="linchaolong",age="unknow",sex="man"}
function add(a,b)
return a+b;
end
testCallCppFun.lua的代码:
result = cppAdd(1,1)
print("call c++ add function result = "..result)
测试代码
LuaTest* lua = new LuaTest;
//获取Lua中的luaStr字符串
CCLOG("lua string = %s",lua->getLuaString("script/test.lua","luaStr"));
//获取Lua中table的字符串
CCLOG("lua table string = %s",lua->getLuaString4Table("script/test.lua","luaTable","name"));
//打印table中的元素
lua->printLuaTable("script/test.lua","luaTable");
//调用lua中的add函数
lua->callLuaAdd("script/test.lua",1,1);
//Lua调用C++中的函数
lua->luaCallCppFunctionTest();
delete lua;注意:
posted on 2014-07-11 16:06 linchaolong 阅读(362) 评论(0) 收藏 举报
浙公网安备 33010602011771号