tolua++初探(九)(转)

来源:互联网 发布:pc传数据到华为mate8 编辑:程序博客网 时间:2024/04/30 14:28
这次驱动文件有了点新的变化:1)两个全局导出函数;2)调用lua函数的代码。分开来看。     导出函数toDerived*很简单,只是调用dynamic_cast来向下转换而已。如果转换失败,dynamic_cast会返回null。当我们 要从基类指针转换到派生类指针时,最好用dynamci_cast,直接强制转换是危险的,除非你明确的知道某个指针指向的对象是什么。     在C++中调用lua脚本的函数大概分为三步:     a..找到函数并入栈;(这里是lua_getglobal(L,"Derived1Test");)     b..参数入栈;(这里是lua_pushlightuserdata(L, p1);)     c..调用lua_pcall进行实际调用     第一步不必说了;第二步可以传递任意个任意类型的参数,lua_pushnumber,lua_pushstring,lua_pushboolean等 等可以调用;第三步是调用lua_pcall,lua_pcall第一个参数是lua_State*,这是我们的工作环境了。第二参数是要传递的参数个 数,我们这里是1;第三个参数是lua函数返回的结果个数,我们的lua函数不返回结果,设为0。第四个参数是比较复杂,为0时指lua_pcall会在 调用失败时把原始错误信息放到栈上;其它值代表栈的索引,该索引处放了一个错误处理函数,lua_pcall失败时会根据这个索引去调用该函数。     调用失败的时候我只是简单地打印一条出错信息,这个错误码放在栈顶,我们用lua_tostring(L,-1)访问并转换为字符串。可以修改下驱动代 码,比如把第二次调用传入p1,这样就可以看见错误信息。     最后我还是在C++代码中打印了下CDerived2对象的值,以验证lua和C++中访问的是同一个对象。    Lua和C++的交互都是通过栈,所以要写交互部分的代码就要不停的出栈入栈,烦死个人。不过这也是Lua灵活的地方。牛人啊,顶礼膜拜吧。     有时间要好好研究下《Programming Lua》,CSDN上有中文版的,lua官方网站上有英文的。虽然这个是针对5.0版本的lua,但绝大部分东西还是有用的。针对5.1.3的第二版已经出了,可惜我在网上没有找到链接,哪位看到分享一下。    下面看看lua文件callluafunc.lua吧:

print("now in CallLuaFunc.lua!")

--lua function to test CDerived1, CDerived2, they'll be called from C++function Derived1Test(e)      d1= toDerived1(e);   

if d1 then

   d1:ShowMessage();

   d1:ShowDerived1();

else

    print("invalid d1(nil)!");

end

end

function Derived2Test(e)

         d2= toDerived2(e);   

           if d2 then

         d2:ShowMessage();

         d2:ShowDerived2();

         d2:SetNumber(180);

         print(d2:GetNumber());

   else

         print("invalid d2(nil)");

     end

end

    lua中定义了函数Derived1Test和Derived2Test。上面的版本已经不会导致出错信息了,原始的Derived*Test函数如下:

function Derived1Test(e)

     d1= toDerived1(e);

     d1:ShowMessage();

     d1:ShowDerived1();

end

function Derived2Test(e)

     d2= toDerived2(e);

     d2:ShowMessage();

     d2:ShowDerived2();

     d2:SetNumber(180);

     print(d2:GetNumber());

end

    原始的Derived*Test函数没有错误检查,所以从C++中用lua_pcall调用时可能会产生错误信息。     又想了下,这样的类型转换太复杂了,tolua++提供了转换机制,可以用的。CEGUI用的就是。     tolua++生成了一些工具函数,在tolua为名的module中。其中tolua.cast就是用来做类型转换的。只需要改动tlclass.pkg文件,加入下面的代码:

$[

    testHelper={}

function testHelper.toDerived1(e)

   return tolua.cast(e,"CDerived1")

end

function testHelper.toDerived2(e)

   return tolua.cast(e,"CDerived2")

end

$]

    $[和$]结合,用来直接插入lua代码。我生成一个名为testHelper的table,给testHelper添加两个转换函数。     重新用tolua++编译,再编译工程。就可以在脚本中调用testHelper.toDerived*来转换了。     下面是更改后的callluafunc.lua文件:

print("now in CallLuaFunc.lua!")

--lua function to test CDerived1, CDerived2, they'll be called from C++function Derived1Test(e)      d1= testHelper.toDerived1(e);

if d1 then

d1:ShowMessage();

d1:ShowDerived1();

else

print("invalid d1(nil)!");

end

end

function Derived2Test(e)

     d2= testHelper.toDerived2(e);

   if d2 then

         d2:ShowMessage();

         d2:ShowDerived2();

         d2:SetNumber(180);

         print(d2:GetNumber());

   else

         print("invalid d2(nil)");

     end

end

    仅仅是将toDerived*调用转换成了testHelper.toDerived*。运行了一下,结果是正常的。        好啦好啦,就到这里啦。     通过两天的学习,我已经确定可以在项目中使用tolua++了,它是"AS IS"的,可以用于任何目的。到目前位置所演示的一些特性,可以满足我的需要。    嗯,有些未完成的东西,比如UNICODE、多线程环境下对lua的调用等,慢慢用到了再说吧。
原创粉丝点击