u3d插件xLua[四]Lua访问C#源码分析,反射,生成代码
本文将致力于研究xLua中Lua访问C#源码分析反射生成代码的用法要理解xLua的源码其实挺难的需要的必备知识比较多C#、Lua、反射、LuaC API一.前言从官网faq中的信息可以得出lua和C#的交互技术有生成代码和反射两种方式官方没有对此作详细的解释。本文致力于从源码上分析梳理展开这部分技术。参考faq.md参考xlua源码分析六 C#与lua的交互总结回顾u3d插件xLua[一]环境搭建和Tutorial分析来看这个demoC#侧的类DerivedClass可以在Lua中当成table来使用CS.Tutorial.DerivedClass。这个实现不是理所当然的有大量代码在对其进行实现下文将探索幕后的内容。二.Demo来看一个Demo所有脚本改动的内容都有对比见下图。Demo展示的内容是通过DoString执行Lua代码时lua中访问C#时(比如下面的local a,local b local c)是执行了C#代码的local a CS.UnityEngine.Vector3 local b CS.UnityEngine.Vector3.up local c CS.UnityEngine.Time.deltaTime打开场景U3DScriptingLuaTestScript.lua.txtLuaBehaviour.csLuaEnv.csObjectTranslator.cs运行打印在Console中的打印可以看出在lua中首次访问类时(比如Vector3)会先走LuaEnv中的元方法function metatable:__index(key) print(***###, key) local fqn rawget(self,.fqn) fqn ((fqn and fqn .. .) or ) .. key然后从这行进入C#local obj import_type(fqn)一直执行到ObjectTranslator.TryDelayWrapLoader这个函数是本文的核心public bool TryDelayWrapLoader(RealStatePtr L, Type type)阅读这个方法可以得出其通过3种方式将C#类本身和类的成员注册到Lua后文将做进一步分析(知道大致逻辑即可无需精细研究)2.1.走CodeEmit类if (!DelegateBridge.Gen_Flag !type.IsEnum() !typeof(Delegate).IsAssignableFrom(type) Utils.IsPublic(type)) { UnityEngine.Debug.Log(TryDelayWrapLoader: type - CodeEmit); Type wrap ce.EmitTypeWrap(type); MethodInfo method wrap.GetMethod(__Register, BindingFlags.Static | BindingFlags.Public); method.Invoke(null, new object[] { L }); }2.2.走Utils.ReflectionWrap(反射)UnityEngine.Debug.Log(TryDelayWrapLoader: type - ReflectionWrap); Utils.ReflectionWrap(L, type, privateAccessibleFlags.Contains(type));2.3.走生成代码if (delayWrap.TryGetValue(type, out loader)) { // 有生成代码走 XxxWrap.__Register UnityEngine.Debug.Log(TryDelayWrapLoader: type - GenWrap.__Register); delayWrap.Remove(type); loader(L); }三.Lua访问C#方式一走CodeEmit类if (!DelegateBridge.Gen_Flag !type.IsEnum() !typeof(Delegate).IsAssignableFrom(type) Utils.IsPublic(type)) { Type wrap ce.EmitTypeWrap(type); MethodInfo method wrap.GetMethod(__Register, BindingFlags.Static | BindingFlags.Public); method.Invoke(null, new object[] { L }); }把这3行代码做的事放一起说在内存中生成*Wrap类然后将类中的成员挂到Lua的表/元表上从而支持Lua → C# 的调用。实现上主要在CodeEmit.EmitTypeWrap中其比较难于理解需要较多System.Reflection.Emit中API的掌握不然看不懂。这里先不展开等用到了再深入研究。public Type EmitTypeWrap(Type toBeWrap)参考生成动态方法和程序集四.Lua访问C#方式二走 Utils.ReflectionWrap(反射)Utils.ReflectionWrap(L, type, privateAccessibleFlags.Contains(type));public static void ReflectionWrap(RealStatePtr L, Type type, bool privateAccessible)static void makeReflectionWrap(RealStatePtr L, Type type, int cls_field, int cls_getter, int cls_setter, int obj_field, int obj_getter, int obj_setter, int obj_meta, out LuaCSFunction item_getter, out LuaCSFunction item_setter, BindingFlags access)ReflectionWrap中通过反射将type的成员挂到lua侧类名这个表中核心实现在makeReflectionWrap中。通过调用LuaAPI.lua_rawset会执行类似t[k] v的操作然后将键和值都从栈中弹出lua_rawset对栈顶附近的数据布局有严格的要求表 (Table)位于栈上的有效索引index处。键 (Key)位于栈顶下方-2位置。值 (Value)位于栈顶-1位置。五.Lua访问C#方式三走生成代码5.1.收集通过GetGenConfig扫一遍当前域里几乎所有类型把配置合并进几个静态列表在MergeCfg中会收集特性LuaCallCSharpAttribute5.2.生成由Generator.GenOne完成写入文件由genCode保存文件文本内容下图是为Vector2类生成UnityEngine_Vector2Wrap.cs的过程5.3.运行第一次Lua访问C#类中成员时由Wrap文件调用RegisterFunc注册来看一个例子LuaTestScript.lua.txtfunction start() print(lua start...) local d CS.XLuaTest.NoGc.a1 end从调用堆栈可以看出调用链为LuaBehaviour.Start-LuaTestScript.Start-...-XLuaTestNoGcWrap.__Register-Utils.RegisterFunc进行注册

相关新闻

AI能力分层时代来临:从Claude Fable 5事件看大模型专业化趋势

AI能力分层时代来临:从Claude Fable 5事件看大模型专业化趋势

1. 项目概述:一次标志性事件的深度复盘最近,AI圈子里一个代号为“Claude Fable 5”或“Mythos 5”的内部事件,引发了远超其代码名称的关注。这并非一次简单的模型版本泄露或功能更新,而是被许多资深从业者视为一个关键的转折点信号…

2026/11/1 7:58:31 阅读更多 →
数学建模竞赛助攻包:AI工具与高频模型实战指南

数学建模竞赛助攻包:AI工具与高频模型实战指南

这次我们来看一个面向2026年全国大学生数学建模竞赛的综合性辅助资源。这个项目不是单一的软件或模型,而是一个整合了选题策略、高频模型、AI工具教程、获奖技巧和写作模板的“助攻包”,目标很直接:帮助零基础或基础薄弱的学生在短时间内&…

2026/10/29 3:57:18 阅读更多 →
AI编程评估新基准:打破唯分数论,从Harness独立性看模型工程鲁棒性

AI编程评估新基准:打破唯分数论,从Harness独立性看模型工程鲁棒性

1. 项目概述:为什么我们需要一个新的基准?最近在AI编程领域,一个名为“SWE-bench”的基准测试火了。简单来说,它就像给AI程序员(比如GPT-4、Claude等大模型)举办的一场“编程奥林匹克”,让它们去…

2026/10/31 8:53:15 阅读更多 →

最新新闻

Electron桌面应用开发实战:从环境搭建到打包发布全流程

Electron桌面应用开发实战:从环境搭建到打包发布全流程

做前端这些年,我大部分时间都在跟浏览器标签页打交道,直到第一次把桌面应用跑起来,才发现原来自己一直被限制在地址栏和刷新按钮围起来的框框里。Electron这个词,最开始是在某段时间频繁出现在同事的讨论里,一个用HTML…

2026/11/2 0:25:10 阅读更多 →
滑盖智能锁T109深度解析:结构原理、安装调试与故障排查

滑盖智能锁T109深度解析:结构原理、安装调试与故障排查

简介:亚太天能T109滑盖智能锁产品说明书是一份PDF格式的官方技术文档,主要面向智能锁安装人员、终端用户及售后维护者,帮助快速掌握产品安装、配置与常见故障处理。全包仅1个PDF文件,大小4.37MB,内容结构清晰&#xff…

2026/11/1 10:36:53 阅读更多 →
PMSM弱磁控制原理与Simulink建模:高速AGV驱动系统设计指南

PMSM弱磁控制原理与Simulink建模:高速AGV驱动系统设计指南

上个月我在调试一台高速AGV的驱动系统,整车要求空载跑到8m/s,电机转速已经拉到额定点,驱动器的输出电压也顶到了母线电压极限附近。再往上踩速度指令,转速纹丝不动,三相电流反而开始震荡。那会儿我的第一反应就是&…

2026/11/1 10:36:51 阅读更多 →
C++核心知识点:从内存管理到STL的实战指南

C++核心知识点:从内存管理到STL的实战指南

C 这门语言我前前后后折腾了十几年,用它写过嵌入式驱动、做过游戏服务端,也搭过基础组件库。每次看到新人一头扎进"C 核心知识点"这个搜索词,我其实挺感慨的——这门语言的难点从来不是语法多,而是知识点之间的耦合太深…

2026/11/1 1:06:58 阅读更多 →
T109滑盖智能锁怎么装?安装调试与故障排查全攻略

T109滑盖智能锁怎么装?安装调试与故障排查全攻略

简介:亚太天能T109滑盖智能锁产品说明书以PDF格式发布,适合智能锁用户、安装人员与售后维修人员阅读。内容围绕T109系列指纹密码刷卡锁展开,先介绍前面板、后面板、锁体、机械钥匙、电池盒盖等部件名称与功能,再给出完整安装步骤&…

2026/11/1 10:35:11 阅读更多 →
LLM知识降熵:从信息垄断到理解权下放

LLM知识降熵:从信息垄断到理解权下放

你有没有过这种经历:翻开源码注释、论文摘要或者一份专业报告,每个字都认识,连在一起却像天书。想找人聊聊,身边要么没人懂,要么懂的懒得跟你解释。后来我试着把同一段内容丢给一个大语言模型,几秒钟之后&a…

2026/11/1 9:35:41 阅读更多 →

日新闻

周新闻

月新闻