tolua框架学习(之三)

      第三个案例讲的是调用lua中的函数方法。核心方法就是luaState中的GetFunction()方法。该方法会先从funcMap这个字典中查找对应的方法对象,有的话,并且该方法仍然处于非游离状态(IsAlive),就会返回该方法,并且从GC列表中删除该方法。否者就会从funcMap中删除该方法对象。

删除该方法对象。

否则,会通过PushLuaFunction方法获取对象。该方法同样也会先在funcMap字典中查找,这一步可以通过参数来跳过。PushLuaTable()会检测该方法的持有者是否已经存在。将方法名拆出来,获取判断该字段对象是否原本代表的是方法类型,获取一个LuaType枚举类型,然后在压堆栈,

设置堆栈。

获取方法对象的堆栈引用,先从funcRefMap字典中通过引用获取方法对象,否则,根据引用创建一个LuaFunction实例对象。设置实例对象的名字为我们需要查找的方法名,并且将其添加进funcMapfuncRefMap两个字典中,最后返回该LuaFunction对象。

返回该LuaFunction对象。

LuaFuntion继承自LuaBaseRef,在本例中,创建LuaFunction实例时,根据单步调试显示,会自动初始化argCount,stackPos,stack这三个字段。同时会在构造方法中初始化refrence字段,该字段继承自LuaBaseRef,在LuaBaseRef中,会从初始化refrence字段,ObjectTranslator对象,count字段和一个IsAlive的bool字段。

一个IsAlive的bool字段。

       示例后面讲的是调用lua方法的几种方法:

       1、使用LuaFunction的成员方法Invoke<>()调用,Invoke有很多重载,基本规律是:最后一个泛型类型就是返回值的类型,前面的泛型类型都是参数的类型。如下图所示:

如下图所示:

方法内部从BeginPCall()开始,结束于EndPCall()。同时,有几个参数就会有几个PushGeneric()方法被执行。BeginPCall()方法会进行一次压栈操作,并且调用LuaState.BeginPCall()从堆栈中返回一个引用。

返回一个引用。

PushGeneric()方法则会调用LuaStatePushGeneric()成员方法,同时会自增argCount的值,该字段是标记方法的参数个数的。LuaState.PushGeneric()方法则是做了一个压栈的操作。

做了一个压栈的操作。

PCall()方法则是调用了LuaStatePCall()成员方法,做了一个异常判断。现在看来,CheckValue()方法应该就是真正执行lua方法的操作了,该方法同样也是包装了LuaState的CheckValue()方法,这个方法是直接从堆栈StackTraits中读取一个值类型的值。而这个堆栈StackTraits正好就是LuaState.PushGeneric()方法压栈的对象。

压栈的对象。

zz

最后EndPCall()方法则是做了出栈,清空等一些操作。

清空等一些操作。

      2、使用自定义的方法来调用lua中的方法。可以看到,该自定义的方法步骤和第一种类似,都是可以一一对应的。其中调用

第一种类似。

的一些核心方法都是一样的。

       3、使用委托来执行lua中的方法。本例中,泛型参数是一个Func委托。该方法需要一个LuaFunction对象参数。

Func委托

Create()方法会先在delegateMap中查找对应引用的对象,如果不为空,则会通过该对象创建一个委托。

则会创建一个。

zz

 否则就创建一个。并赋值方法,返回该委托。

否则就创建一个。

执行该委托,调用的是System_Func_int_int_EventCall成员方法。其内部的具体实现

和​​​​​​​上面的差不多。

      4、使用LuaStateInvoke()成员方法,该成员方法也有很多重载,规律和LuaFunction的Invoke方法一样。内部实现也很类似。

内部实现也很类似。

猜你喜欢

转载自blog.csdn.net/Tong1993222/article/details/83217905