转载自:深入理解xLua基于IL代码注入的热更新原理 - iwiniwin - 博客园 (cnblogs.com)
例子:
第一步:GenerateCode:为打了Hotfix标签的方法生成对应的匹配函数
[Hotfix] public class TestXLua { public int Add(int a, int b) { return a - b; // 这里的Add方法故意写成减法,后面通过热更新修复 } }
会在配置的Gen目录下生成DelegatesGensBridge.cs文件,其中有为TestXLua.Add生成的对应的匹配函数__Gen_Delegate_Imp1
// DelegatesGensBridge.cs public partial class DelegateBridge : DelegateBridgeBase { // ... public int __Gen_Delegate_Imp1(object p0, int p1, int p2) { #if THREAD_SAFE || HOTFIX_ENABLE lock (luaEnv.luaEnvLock) { #endif RealStatePtr L = luaEnv.rawL; int errFunc = LuaAPI.pcall_prepare(L, errorFuncRef, luaReference); ObjectTranslator translator = luaEnv.translator; translator.PushAny(L, p0); LuaAPI.xlua_pushinteger(L, p1); LuaAPI.xlua_pushinteger(L, p2); PCall(L, 3, 1, errFunc); int __gen_ret = LuaAPI.xlua_tointeger(L, errFunc + 1); LuaAPI.lua_settop(L, errFunc - 1); return __gen_ret; #if THREAD_SAFE || HOTFIX_ENABLE } #endif } // ... }
这样的话,调用传递给C#的lua函数就相当于调用以"__Gen_Delegate_Imp"开头的生成函数,这个生成函数负责参数压栈,并通过保存的索引获取到真正的Lua function,然后使用lua_pcall完成Lua function的调用。
第二步:IL注入
为TestXlua添加一个名为"__Hotfix0_Add"的DelegateBridge类型的静态变量。并在原来的Add方法中注入判断静态变量是否不为空,如果不为空就调用静态变量所对应的Lua方法的逻辑。反编译已注入IL代码的Assembly-CSharp.dll,查看其中的TestXLua如下所示:
using System; using XLua; // Token: 0x02000016 RID: 22 [Hotfix(HotfixFlag.Stateless)] public class TestXLua { // Token: 0x06000051 RID: 81 RVA: 0x00002CE0 File Offset: 0x00000EE0 public int Add(int a, int b) { DelegateBridge _Hotfix0_Add = TestXLua.__Hotfix0_Add; if (_Hotfix0_Add != null) { return _Hotfix0_Add.__Gen_Delegate_Imp1(this, a, b); } return a - b; } // Token: 0x06000052 RID: 82 RVA: 0x00002D14 File Offset: 0x00000F14 public TestXLua() { DelegateBridge c__Hotfix0_ctor = TestXLua._c__Hotfix0_ctor; if (c__Hotfix0_ctor != null) { c__Hotfix0_ctor.__Gen_Delegate_Imp2(this); } } // Token: 0x04000022 RID: 34 private static DelegateBridge __Hotfix0_Add; // Token: 0x04000023 RID: 35 private static DelegateBridge _c__Hotfix0_ctor; }
第三步:绑定Lua函数
在打补丁时通过xlua.hotfix为静态变量"__Hotfix0_Add"设置一个Lua函数。这样下次调用TestXLua.Add时,"__Hotfix0_Add"将不为空,此时将执行_Hotfix0_Add.__Gen_Delegate_Imp1,即调用设置的Lua函数,而不再执行原有逻辑。从而实现了C#热修复。
标签:__,int,流程,Xlua,Add,TestXLua,Hotfix0,public From: https://www.cnblogs.com/mcyushao/p/17349921.html