Cocos2d-x中Lua与C++通信

来源:互联网 发布:mysql保存特殊字符 编辑:程序博客网 时间:2024/04/28 07:20


参考文章地址: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++声明


LuaTest.h的代码:
#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++实现


LuaTest.cpp的代码:
#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);//如果栈顶元素是一个tableif(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);//迭代tablewhile (lua_next(L,top))//key出栈,key-value入栈(如果table中还有元素){//获取keyconst char* key = lua_tostring(L,-2);//获取valueconst 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;

注意:
1.C++调用Lua函数时,该Lua函数必须是全局的;
2.Lua调用C++函数时,该C++函数必须是静态的;

0 0
原创粉丝点击