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;
    }
  1. 定义委托
  2. 定义委托对应函数
  3. 将方法转为指针
  4. 将函数入栈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场景

  • 2
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值