C++与tolua++的完整调用流程,超级详解解决交互疑难!!!

来源:互联网 发布:淘宝手机模拟器安卓版 编辑:程序博客网 时间:2024/05/21 11:29

C++要想跟tolua完整的相互调用,中间需要很多的库和执行程序,包括tolua.lib  tolua++.exe等交互。

1、必须先下载lua 1.5,下载好后,把/src目录的除开lua.c,luac.c的文件全部放到一个新建的静态链接库的工程项目里,然后编译出一个静态链接库xxxxx.lib。

2、去tolua++官网下载一个tolua++的包,解压出来,再次新建一个静态链接库的项目,把tolua++的/src/lib里的.h .c的文件拷贝到静态链接库的项目里,然后编译出一个XXX++.lib 的库。

3、再次新建一个控制台程序的项目,把编译好的lua静态库和tolua++的静态库放在项目里附加,然后把tolua++的/src/bin/里的tolua.c,luabind.h,luabind.c文件放在项目里,然后把tolua++的/include里的tolua++.h和lua1.5的目录里的/src的所有头文件放到项目里,然后编译生成xxxx++.exe

4、预备工作做好了,现在要了解一下tolua++的一些概念,要想c++与tolua交互,我们需要两个文件,一个是用来解析pkg文件的C++代码,和一个编译好的tolua++.lib或者.dll的静态或动态库,

   tolua通过pkg文件解析捆绑c++代码,生成一个解析好的lua能识别的文件(就是通过编译好的xxx++.exe控制台程序生成的),我们通过一串命令来执行生成

  tolua -n 链接的名字 -o /xxxx.h或者.cpp  xxxxx.pkg

  这样lua就可以调用C++的代码了,pkg文件也有一些规范,具体规范请参考http://blog.csdn.net/OBsona/archive/2008/12/08/3478518.aspx

所有lua的API函数中文解释参考

http://blogold.chinaunix.net/u/18584/showart_2098629.html

 

lua调用C++的方式

  首先编辑好解析的pkg和生成链接lua的文件,然后在主运行入口里main()

 

 加载lua文件

  lua_State* L = lua_open();
 luaL_openlibs(L);

 tolua_xxxx(链接的名字)_open(L); 
 luaL_dofile(L, "xxxxx.lua");

 lua_close(L);

 

C++调用lua的方式(最复杂的)

  1、由于tolua没有完整的封装C++调用的lua的方式,对于习惯C++调用函数和变量的人来说有点别扭,不过可以尝试自己封装

  C++调用lua的函数和全局变量,都要通过入栈出栈的方式调用。

   可以这样理解,我们调用luaL_dofile(L,"xxx.lua")时,就把lua相应的函数和变量放在一个内存栈里了,当我们需要调用lua的函数或者变量时,就把相应名字索引的栈空间值重新压入到一个新的栈里进行操作。

  lua_State* L = lua_open();
 luaL_openlibs(L);

 tolua_xxxx(链接的名字)_open(L); 
 luaL_dofile(L, "xxxxx.lua");

 

2、调用基本类型变量

lua_getglobal(L,"demo");(demo具体的函数名或者变量)

这个值在栈顶,现在加入我们要取得一个lua的全局变量demo,我们已经把变量压到栈里,现在就是取出它的时候

type demo = lua_tonumber(L,-1);在这里具体取出什么类型的值,请看上面的API,lua的栈取值的索引很有趣,可以正着取也可以反着取,通常是反着取,就是从栈顶向下数,-1就是栈顶.

 

3、调用函数(无参)

现在我们取一个函数试试,这个函数假设没参数

(  xxx.lua里

   function TestFuc()

      print("lua脚本函数")

  end

)

lua_getglobal(L,"TestFuc");

 

lua_pcall(L,0,0,0);调用lua函数需要调用这个接口,第二参数为函数的参数个数,第三参数为返回参数个数,第四参数为错误信息,当调用lua函数错误时会返回相应的错误信息

4、重点,调用函数(带参数)

(  xxx.lua里

   function TestFuc(xxx)

      xxxxx........

  end

)

lua_getglobal(L,"TestFuc");

由于不同的参数调用不同故分开写

     传入数字类型时

    lua_pushnumber(L,250);压入第一个参数当做函数的第一个参数也可以用tolua_pushnumber(L,250)

    传入字符串类型时

    lua_pushstring(L,"hello world");或者

    std::string temp("hello world");

   lua_pushstring(L,temp.c_str());

    传入一个表结构时

    lua_newtable(L);首先先创建一个空表到栈里 假设表为tab = {[1]="array1",[2]="array2",[3]={"aaa","bbb"}}

    lua_pushnumber(L,1);传入KEY

    lua_pushstring(L,"array1");传入值

   lua_settable(L,-3);找到表的栈的位置,设置键和值进入,这里注意只能一对键值对的设置,不能一起设置

    lua_pushnumber(L,2);传入KEY

    lua_pushstring(L,"array2");传入值

    lua_settable(L,-3);

    嵌套表的插入

    lua_newtable(L);

    lua_pushnumber(L,1);传入KEY

    lua_pushstring(L,"aaa");传入值

    lua_settable(L,-3);

    lua_pushnumber(L,2);传入KEY

    lua_pushstring(L,"bbb");传入值

    lua_settable(L,-3);

 

    lua_settable(L,-3);

这里可能对栈里表的位置有疑惑,明明又压入两个元素为什么表的位置还是-3,设置一次表后,参数会被pop出栈,跟调用函数一样,调用完函数之后参数会被pop出栈 

参数是C++对象的时

(  xxx.lua里

   function TestFuc(testClass)

      local name=testClass.m_name

      testClass:testFuc()

      testClass.m_name="dfdfdf"

  end

)

    需要预先通过pkg生成解析文件,lua通过解析文件能知道C++的自定义类型

    假设pkg里解析了一个类testClass   里面有一个成员变量m_name和成员函数testFuc()

    只要有解析文件,我们只需要把解析好的类型指针传入即可

    testClass* tempPtr= new testClass;

    tolua_pushusertype(L,tempPtr,"testClass");

 

 lua_close(L);

 

 

原创粉丝点击