Lua与C#交互原理(转)
https://www.cnblogs.com/slysky/p/7919114.html
https://blog.csdn.net/j756915370/article/details/105906839
概括:
通过栈来实现。lua调用c#就是将lua层的参数和c#导出函数入栈,然后执行函数。c#调用lua就是将c#层的参数和lua函数入栈,然后执行函数
虚拟栈
Lua在C函数和脚本函数之间创建了一种虚拟栈的结构,栈的元素代表一个Lua的值(table, string, nil等等8种基本类型)。Lua提供了一系列C API用于操作栈,比如将元素入栈,出栈,删除等等。在调用这些API之前,通常都需要将必须的值压入栈,在API调用结束后,再把结果从栈中取出。记住越往下越小,1表示栈底,-1表示栈顶
luaState的概念
luaState 中放的是 lua 虚拟机中的环境表、注册表、运行堆栈、虚拟机的上下文等数据。可以理解为我们写代码常用的各种manager类。在xLua中luaState被封装成了LuaEnv类,在toLua中叫作LuaState。
var L = LuaDLL.luaL_newstate();
lua_pcall
lua_pcall(lua_State *L,int nargs,int nresults,int errfunc) nargs 参数个数 nresults 返回值个数 errFunc 错误处理函数,0表示无,表示错误处理函数在栈中的索引
C#调用Lua:传入C#参数,调用Lua方法
lua代码
function addandsub(x,y) return x+y,x-y end
C#把C#端参数入栈,lua_pcall调用,lua中返回值,依次放入栈顶
private void CallLuaFunction( IntPtr L ) { var path = Application.dataPath + "/LuaTest/Examples/03_Function/03.lua"; Debug.Log(path); LuaDLL.luaL_loadfile( L, path );//执行lua文件,也可以luaL_dostring(L, string);执行lua字符串代码 LuaDLL.lua_pcall( L, 0, 0, 0 ); LuaDLL.lua_getglobal( L, "addandsub");//获取全局变量的addandsub的值,并将其放入栈顶 LuaDLL.lua_pushnumber( L, 10 );//栈顶压入10 LuaDLL.lua_pushnumber( L, 20 );//栈顶压入20 if( LuaDLL.lua_pcall( L, 2, 2, 0 ) != 0 ) //执行函数,输入2个值,返回2个值,不为0,有错误 { Debug.LogError( LuaDLL.lua_tostring( L, -1 ) ); } Debug.Log( LuaDLL.lua_tonumber( L, -1 ) );//栈-2,为-10 Debug.Log( LuaDLL.lua_tonumber( L, -2 ) );//栈-1,为30,,因为返回值是先入栈 }
1.先将方法入栈
2.再将方法需要的参数按顺序入栈
3.调用 lua_pcall
4.此时lua会把返回值入栈
Lua调用C#
private void LuaHelloWorld( IntPtr L ) { LuaDLL.lua_pushcclosure( L, HelloWorld, 0 ); LuaDLL.lua_pcall( L, 0, 0, 0 ); } [MonoPInvokeCallbackAttribute( typeof( LuaCSFunction ) )] private static int HelloWorld( IntPtr L) { Debug.Log( "helloworld:" ); return 0; }
- 定义委托
- 定义委托对应函数
- 将方法转为指针
- 将函数入栈lua_pushcclosure
其他相关
https://www.cnblogs.com/huangzongyi/p/7777635.html
Lua调用C#函数,并传入参数
// 新建一个Lua解释器,每一个Lua实例都相互独立, 一个global全局域 Lua lua = new Lua(); //---------------------------------------------------lua调用c#函数 TestClass obj = new TestClass(); // 注册CLR对象方法到Lua,供Lua调用 typeof(TestClass).GetMethod("TestPrint") lua.RegisterFunction("TestPrint", obj, obj.GetType().GetMethod("TestPrint")); // 注册CLR静态方法到Lua,供Lua调用 lua.RegisterFunction("TestStaticPrint", null, typeof(TestClass).GetMethod("TestStaticPrint")); lua.DoString("TestPrint(10)"); lua.DoString("TestStaticPrint()");
CLR(Common Language Runtime)是一个可由多种编程语言使用的“运行时”。(例如:c#,c++/cli,vb,f#,ironpython,ironruby,il…)
CLR的核心功能内存管理、程序集加载、安全性、异常处理、线程同步、泛型、尾调用指令和基本的公共语言基础结构 (CLI) 类型系统等。
本地代码编译器生成的是面向特定cpu架构的代码。相反每个面向clr的编译器生成的都是il代码。源代码文件----》编译器----》托管模块
测试用代码
https://github.com/luoyikun/UnityForTest
Lua2CSharpTest场景
posted on 2022-03-10 22:30 luoyikun 阅读(42) 评论(0) 编辑 收藏 举报 来源
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· C#/.NET/.NET Core优秀项目和框架2025年2月简报
· DeepSeek在M芯片Mac上本地化部署
· 葡萄城 AI 搜索升级:DeepSeek 加持,客户体验更智能