1.slua调用Unity接口过程分析
2.tolua源码分析(五)lua使用C#的源码enum
3.Lua的编译和反编译
4.(Unity) 为被 Lua 隔断的 C# 实现添加 Profiler 支持
slua调用Unity接口过程分析
slua将Unity3D类导出为wrapper类,以便Lua与C#交互。源码以GameObject为例,源码Lua中调用的源码GetComponent方法会首先调用C#层的Lua_UnityEngine_GameObject类中注册的GetComponent方法。该方法首先通过checkSelf函数获取C#中的源码go对象,然后在C#层直接调用go.GetComponent,源码建筑网站源码最后将component对象返回给Lua。源码关键点在于通过对象id实现C#与Lua之间的源码交互,分配id并放入cache,源码使得checkSelf函数可通过id获取C#对象。源码同样,源码获取的源码component对象也是通过id形式,经过C作为桥梁返回至Lua。源码
tolua源码分析(五)lua使用C#的源码enum
探讨了C#枚举如何在Lua中注册以及与普通类的注册区别。以官方提供的源码例子为例,展示了如何将C#的UnityEngine.Space类型的枚举推送到Lua层,并在Lua层面测试了诸如tostring、ToInt、负十五减九用源码计算Equals等接口,验证了在Lua层可以进行枚举的相等判断,以及将int转换为枚举或将枚举转换为int的操作。
在Lua层面表示C#的枚举,例子中在第行和第行将枚举推送到Lua层。由于枚举是值类型,C#层使用了enumMap缓存装箱后的object与枚举的映射关系。注册到Lua层的枚举类使用了EnumMetatable。
具体来看C#枚举注册到Lua的方法,例如在System_EnumWrap.Register方法中。在Lua层表示C#枚举的方式与普通类相似,但需要注意一些区别。
例如,当使用__tostring方法时,ToLua.ToObject将Lua栈上的userdata转换为object,通过userdata的index查找C#的object缓存,不会产生垃圾收集(GC)。中科院溯源码准吗同样地,ToInt方法中的CheckObject同样在C#的object缓存中查找,执行类型检查,也不会产生GC。
当比较C#的枚举与int类型时,由于使用了==操作符,这会触发装箱,产生一次GC。因此,在实际使用中应尽量避免在Lua层对C#枚举与number进行比较。而在Lua层直接比较两个C#枚举时,它们在Lua层被视为同一份userdata,因为它们来自于同一个C#缓存,index相同。
在将Lua栈上的number转换为C#枚举的实例时,IntToEnum方法在C#的UnityEngine_SpaceWrap类中实现。这个方法直接将double转换为int,放量假阴真阳指标源码再转换为UnityEngine.Space类型,避免了GC。在C#层推送到Lua层的枚举时,是从C#的缓存中取到枚举对应的object,然后推送到Lua层,也不会产生GC。
总结,在Lua使用C#的枚举时,从C#到Lua层的传递不会产生GC,在Lua层进行number与枚举类型之间的转换以及直接比较枚举时不触发GC。然而,当比较枚举与number时,会触发一次GC。针对这一情况,可以进行针对性优化。
下一节将深入研究在开发中常见的C#委托/事件如何注册到Lua函数的实现。
Lua的易语言动态显示物体源码编译和反编译
无论是Unity项目还是Unreal的项目,我通常会使用Lua进行编程。在项目打包阶段,Lua的编译和反编译是不可或缺的步骤。在本文中,我们将探讨如何对Lua代码进行编译与反编译,以及如何利用不同的工具进行操作。
对于Lua代码的编译,我们通常有两种方法。一种是使用lua脚本直接运行代码,另一种是使用Lua的编译器(如Luac)将源代码转换为Lua字节码。通过使用指令`lua ./TestLua.lua`,我们可以测试代码的正确性。Luac是将Lua源代码编译为Lua字节码的工具,编译成功后,我们可以通过运行编译后的字节码来验证结果,一切顺利。
另一种流行的Lua编译器是Luajit,它在Unity项目中被广泛使用。使用Luajit可以提升执行速度。如果遇到编译错误,只需确保将`luajit\src\src\jit`文件放在`luajit.exe`的同一目录下的`lua`文件夹中即可。通过直接运行包含测试代码的Lua文件,我们可以确认编译和运行的流程是正确的。
在对比了两种编译方法后,我们发现它们都有各自的特点和适用场景。Luac适用于简单的脚本或对代码优化要求不高的情况,而Luajit则更适合需要高性能的项目,特别是那些对运行速度有较高要求的场景。
对于Lua的反编译,最常用的工具是`luadec`。通过将`luadec`工具与Visual Studio项目进行集成,我们能够对编译后的字节码进行反编译,恢复源代码。在尝试反编译后,我们得到了清晰可读的代码,即使在不使用调试信息的情况下,反编译结果也具有一定的可读性。
对于更复杂的反编译需求,如支持位字节码的反编译,我们遇到了一些挑战。目前,有一个名为`ljd`的工具支持位字节码的反编译,但仅限于位平台。对于位平台的字节码,我们可能需要自行修改`ljd`的Python代码来支持,这是一个需要时间和专业知识的额外工作。尽管如此,对于大部分应用场景,上述工具已经足够满足我们的需求。
总之,Lua的编译和反编译是Lua项目开发过程中的重要环节。通过选择合适的编译工具和反编译方法,可以有效提升代码的执行效率和调试效率。同时,对于反编译过程,我们应根据实际需求选择合适的工具,并注意其适用的平台和特性。
(Unity) 为被 Lua 隔断的 C# 实现添加 Profiler 支持
在Unity项目中,由于Lua的灵活性和与服务器代码共享的优势,许多团队倾向于采用Lua作为上层逻辑脚本。然而,这种“全暴露”方式导致C#与Lua之间的交互层封闭,阻碍了Unity Profiler等引擎内置工具的使用,特别是当C#和Lua接口数量庞大时。Profiler无法跨越C#和Lua的界限,无法深入剖析Lua函数的性能问题,特别是内存分配导致的GC卡顿。
通常的做法是通过在C#代码中添加Profiler采样,然后回溯到Lua脚本,分析可能的性能瓶颈。然而,这往往需要反复在脚本和C#之间切换,耗时且增加理解代码的复杂性。面对这个问题,人们寻求更直接的解决方案,比如使用AOP(面向切面编程)来自动为暴露给Lua的C#接口添加性能剖析。然而,现有的C# AOP方法在Unity的mono环境中并未成功应用。
转而,作者尝试通过修改slua生成的代码,直接在接口绑定函数中加入Profiler采样。首先,找到函数接口的生成位置,然后在函数前后添加BeginSample和EndSample代码,实现对特定类和函数的粒度控制。尽管这一方法可能解决了Profiler支持的问题,但实际操作中仍面临lambda expression不支持添加attribute的限制。
总的来说,虽然通过slua的代码生成实现了一种解决方案,但这个过程并不完全透明,且需要对底层代码进行修改。这表明在Unity与Lua的集成中,为Profiler提供完整支持仍存在挑战,需要进一步的探索和优化。