C#与Lua交互过程:
C# Call Lua :由C#文件先调用Lua解析器底层dll库(由C语言编写),再由dll文件执行相应的Lua文件;
Lua Call C# :
(1)、Wrap方式:首先生成C#源文件所对应的Wrap文件,由Lua文件调用Wrap文件,再由Wrap文件调用C#文件;
- a.生成时,有宏定义的方法,如Editor会有问题
- b.生成的代码,增大编译后的代码大小,尤其il2cpp,相应地增加包体大小
(2)反射方式:当索引系统API、dll库或者第三方库时,如果无法将代码的具体实现进行代码生成,可采用此方式实现交互。缺点:执行效率低。
- a.拆装箱开销
- b.stripping引用的反射失效
- c.泛型方法,触发JIT,引起IOS异常
- d.失去静态检查好处
C#与Lua交互原理:
C#与Lua进行交互主要通过虚拟栈实现,栈的索引分为正数与负数,若果索引为正数,则1表示栈底,若果索引为负数,则-1表示栈顶。
C# Call Lua:由C#先将数据放入栈中,由lua去栈中获取数据,然后返回数据对应的值到栈顶,再由栈顶返回至C#。
Lua Call C#:先生成C#源文件所对应的Wrap文件或者编写C#源文件所对应的c模块,然后将源文件内容通过Wrap文件或者C模块注册到Lua解释器中,然后由Lua去调用这个模块的函数。
从代码文件方面解释:
lua调用CSharp过程:
lua->wrap->C#
先生成Wrap文件(中间文件/适配文件),wrap文件把字段方法,注册到lua虚拟机中(解释器luajit),然后lua通过wrap就可以调C#了
或者在config文件中添加相应类型也可以
CSharp调用Lua过程:
C#生成Bridge文件,Bridge调dll文件(dll是用C写的库),先调用lua中dll文件,由dll文件执行lua代码
C#->Bridge->dll->Lua OR C#->dll->Lua
从内存方面解释:说白了就是对栈进行操作
C# Call Lua:C#把请求或数据放在栈顶,然后lua从栈顶取出该数据,在lua中做出相应处理(查询,改变),然后把处理结果放回栈顶,最后C#再从栈顶取出lua处理完的数据,完成交互。
注意:
1,每一个函数都有一个私有栈并且第一个参数就是在栈的1位置,后面以此类推有几个参数就有多少个
2,如果函数返回结果,第一个结果被第一个入栈,因此如果有n个返回结果,第一个返回结果在栈中的位置为-n,最后一个返回结果在栈中的位置为-1
c#就是在这基础之上又调用了C api所以相信大家在看c#与lua也就明白很多了。也知道为什么要进行wrap,wrap之后为什么可以直接使用了。(向lua注册的函数必须要有这样的结构返回值为int传入参数为lua_State* typedef int (*lua_CFunction) (lua_State *L);)
可以从luaenv中分离出新的luastate线程,luastate与主线程共享全局空间,并且拥有独立的执行环境。