闲鱼技术01 发表于 2021-8-14 22:49

XLua心得

一. xlua简介
   xlua是由腾讯维护的一个开源项目,除了常规的Lua绑定之外,还有一个比较有特色的功能就是代码热补丁。非常适合前期没有规划使用Lua进行逻辑开发,后期又需要在iOS这种平台获得代码热更新能力的项目。
刚开始学习使用xlua,主要实现原理暂时还未进行深究,研究过后将会在之后的内容里补上。这里先祭上官方的一张图来简单描述一下:




传送门系列:

官网:
https://github.com/Tencent/xLua
配置文档:
https://github.com/Tencent/xLua/blob/master/Assets/XLua/Doc/hotfix.md
官方FAQ:
https://github.com/Tencent/xLua/blob/master/Assets/XLua/Doc/faq.md
代码生成引擎:
https://github.com/Tencent/xLua/blob/master/Assets/XLua/Doc/custom_generate.md
Lua5.3官方手册:
https://www.lua.org/manual/5.3/manual.html

    关于xlua和lua的基础知识,在官网上和其他一些教程里都有详细的描述,我这边就不贴了,这次主要说一下我在学习使用xlua时遇到的问题已经需要注意的一些地方,最后奉上自己使用Unity和xlua交互制作的一个小程序和一个xlua热更新的例子。好的,那我就先从热更新开始啦~

二.xlua热更新


    第一,当然是将xlua添加到我们的工程里,在github上下载xlua之后,将 xlua-master/Assets下的内容拷贝到我们的工程里,因为之后制作热更新的时候需要使用tools文件夹下的XLuaHotfixInject.exe 文件,所以我这边直接将tools文件也整个拷贝到工程里,在真实的项目里大家根据需求有选择的拷贝就好。另外有一点需要注意的是,全拷贝tools文件夹下的内容到工程里的话,Unity会报出重复定义的错误:




此时,将tools里的 System.Core.dll 删除就可以了。
    第二,在BuildSettings里添加两个宏:
   HOTFIX_ENABLE:开启热更新特性,编辑器,各手机平台需要手动单独设置,如果是自动化打包,要注意在代码里用API设置的宏是不生效的,需要在编辑器里设置。
   INJECT_WITHOUT_TOOL:采用内嵌到编辑器的方式注入。添加了该宏之后,在菜单栏XLUA里才能够进行【Hotfix inject in Editor】的操作;在构建手机包的时候这个步骤会在构建时自动进行,编辑器模式下开发补丁需要手动执行Hotfix inject in Editor进行注入。
   定义INJECT_WITHOUT_TOOL宏后,热补丁特性依赖Cecil,添加HOTFIX_ENABLE宏之后,可能会报找不到Cecil。这时你需要到Unity安装目录下找到Mono.Cecil.dll,Mono.Cecil.Pdb.dll,Mono.Cecil.Mdb.dll,拷贝到项目里头。
    注意:如果你的Unity安装目录没有Mono.Cecil.Pdb.dll,Mono.Cecil.Mdb.dll(往往是一些老版本),那就只拷贝Mono.Cecil.dll(你从别的版本的Unity拷贝一套可能会导致编辑器不稳定),这时你需要定义HOTFIX_SYMBOLS_DISABLE,
    这会导致C#代码没法调试以及Log的栈源文件及行号错乱(所以赶紧升级Unity)。

    以上两个宏若是不开启,或者在没有成功进行Hotfix inject in Editor操作直接运行的话,系统会抛出 LuaException: xlua.access, no field __Hotfix0_hotfix


第三,对需要热更的代码部分添加标签,这样xLua就知道这个类或者方法等可能会有热更新的需求。
   纯文本查看复制代码
?

      01      
      02      
      03      
      04      
      05      
      06      
      07      
      08      
      09      
      10      
      11      
usingUnityEngine;
usingSystem.Collections;
usingXLua;


publicclassHotfixTest_easy{

publicvoidHotFixEasy()
{
Debug.Log("Unity调用");
}
}






    第四,Unity侧的调用:
   纯文本查看复制代码
?

      01      
      02      
      03      
      04      
      05      
      06      
      07      
      08      
      09      
      10      
      11      
      12      
      13      
      14      
      15      
      16      
      17      
      18      
      19      
      20      
      21      
      22      
      23      
      24      
      25      
      26      
      27      
      28      
      29      
      30      
      31      
      32      
      33      
      34      
      35      
      36      
      37      
      38      
usingUnityEngine;
usingSystem.Collections;
usingXLua;

publicclassHotFixMono : MonoBehaviour {

XLua.LuaEnv m_kLuaEnv = null;

privateHotfixTest_easy fixEasy = null;
// Use this for initialization
privateboolisShow = false;
voidStart () {

//代码热更步骤
m_kLuaEnv = newLuaEnv();//该变量最好保证全局就此一个

//1.查找指定路径下lua热更文件
TextAsset txt = Resources.Load("HotfixTest_easy.lua") asTextAsset;

//2.如果存在lua热更文件,则执行lua文件的执行,否则不执行(也就是说,到底是读取C#本地代码还是LUA热更代码是由我们自己控制,xlua框架并不提供识别机制,这只是我现在的个人理解,如果不正确,请一定要告知我!)
if(txt != null)
{
m_kLuaEnv.DoString(txt.text, "HotfixTest_easy.HotFixEasy");//这个方式是替换指定的方法
}

fixEasy = newHotfixTest_easy();
}

// Update is called once per frame
voidUpdate()
{

if(!isShow)
{
isShow = true;
fixEasy.HotFixEasy();
}
}
}






    第五,Lua侧(蛮牛不能插入lua的代码,看起来很不方便啊):
HotfixTest_easy = {}

function HotfixTest_easy.HotFixEasy()
      print("xxxxxxx lua cast")
end;

xlua.private_accessible(CS.HotfixTest_easy)
xlua.hotfix(CS.HotfixTest_easy,'HotFixEasy',HotfixTest_easy.HotFixEasy)

几个重要的xlua API:
xlua.hotfix(class, , fix)
描述 : 注入lua补丁
class : C#类,两种表示方法,CS.Namespace.TypeName或者字符串方式"Namespace.TypeName",字符串格式和C#的Type.GetType要求一致,如果是内嵌类型(Nested Type)是非Public类型的话,只能用字符串方式表示"Namespace.TypeName+NestedTypeName";
method_name : 方法名,可选;
fix : 如果传了method_name,fix将会是一个function,否则通过table提供一组函数。table的组织按key是method_name,value是function的方式。

xlua.private_accessible(class)

描述 : 让一个类的私有字段,属性,方法等可用
class : 同xlua.hotfix的class参数

util.hotfix_ex(class, method_name, fix)
描述 : xlua.hotfix的增强版本,可以在fix函数里头执行原来的函数,缺点是fix的执行会略慢。
method_name : 方法名;
fix : 用来替换C#方法的lua function。

第六,执行xlua/Generate Code--->执行XLua/Hotfix Inject In Editor,其中,执行后者的时候,因为XLUA源代码里需要找到XLuaHotfixInject.exe(tools里)才能运行,需要收到修改代码里找到该文件的路径(反正为了运行我暂时先改了)

第七,运行。

运行结果:

当热更新目录(我这里为了方便暂时放在Resource文件夹下)里不存在指定的文件时,则执行C#定义的方法:







当存在指定的文件时,则进行热更新的操作:







以上仅仅用一个简单的例子给大家掩饰了使用xlua进行代码热更新的流程,还有很多xlua强大的功能没有涉及到,本文也是一个抛砖引玉,最主要的还是记录我自己学习过程,我没有弟子来记录我平时的言行语录,我就自己来!
页: [1]
查看完整版本: XLua心得