zoukankan      html  css  js  c++  java
  • [Lua]与c#的交互(二)

    参考链接:

    https://www.cnblogs.com/lijiajia/p/8284328.html

    https://www.jianshu.com/p/7cc9ca7efe18

    http://www.360doc.com/content/16/0830/21/7014874_587111940.shtml#

    零.原理

    lua与其他语言的交互,都是基于栈的结构来交互的。栈的元素为lua中的值(table,string,nil等8种基本类型)

    如果用正数索引来表示,则栈底为1,索引往上递增;如果用负数索引来表示,则栈顶为-1,索引往下递减

    lua与其他语言的交互过程如下:

    一.c#调用lua

     1 using LuaInterface;
     2 using System;
     3 
     4 namespace TestLua
     5 {
     6     class Program
     7     {
     8         static IntPtr L;
     9 
    10         static void Main(string[] args)
    11         {
    12             int sum;
    13             L = LuaDLL.luaL_newstate();//创建lua状态机
    14             LuaDLL.luaL_openlibs(L);//打开Lua状态机中所有Lua标准库
    15             LuaDLL.luaL_dofile(L, "add.lua");//加载lua脚本
    16             sum = LuaAdd(8, 9);
    17             Console.WriteLine(sum);
    18             LuaDLL.lua_close(L);//关闭lua状态机
    19             Console.ReadKey();
    20         }
    21 
    22         static int LuaAdd(int x, int y)
    23         {
    24             int sum = -1;
    25             LuaDLL.lua_getglobal(L, "AddFunc");//函数名
    26             LuaDLL.lua_pushnumber(L, x);//参数入栈
    27             LuaDLL.lua_pushnumber(L, y);//参数入栈
    28             LuaDLL.lua_call(L, 2, 1);//开始调用函数,有2个参数,1个返回值
    29             sum = (int)LuaDLL.lua_tonumber(L, -1);//取出返回值
    30             LuaDLL.lua_pop(L, 1);
    31             return sum;
    32         }
    33     }
    34 }

    add.lua

    1 function AddFunc(x,y)
    2     return x + y
    3 end

    输出:

    分析:

    lua_getglobal(L, "AddFunc"),将lua中的全局变量AddFunc进栈

    lua_pushnumber(L, x),将参数x进栈,当2个参数都进栈后,栈是这样的(从栈底到栈顶):AddFunc->8->9

    lua_call(L, 2, 1),调用后,栈的元素都出栈,然后返回值进栈,栈是这样的(从栈底到栈顶):17

    lua_tonumber(L, -1),将栈顶元素转换为number用于赋值

    lua_pop(L, 1),栈顶元素出栈,此时栈为空

    二.lua调用c#

     1 using LuaInterface;
     2 using System;
     3 
     4 namespace TestLua
     5 {
     6     class Program
     7     {
     8         static void Main(string[] args)
     9         {
    10             IntPtr L = LuaDLL.luaL_newstate();//创建lua状态机
    11             LuaDLL.luaL_openlibs(L);//打开Lua状态机中所有Lua标准库
    12             LuaDLL.lua_pushstdcallcfunction(L, SayHello);
    13             LuaDLL.lua_setglobal(L, "AAA");
    14             LuaDLL.luaL_dostring(L, "print(AAA("123"))");
    15             LuaDLL.lua_close(L);//关闭lua状态机
    16             Console.ReadKey();
    17         }
    18 
    19         static int SayHello(IntPtr L)
    20         {
    21             string s = LuaDLL.lua_tostring(L, 1);
    22             LuaDLL.lua_pushstring(L, "Hello " + s);
    23             return 1;
    24         }
    25     }
    26 }

    输出:

    分析:

    lua_pushstdcallcfunction(L, SayHello),将c#的方法SayHello进栈

    lua_setglobal(L, "AAA"),将栈顶元素设置成lua中的全局变量AAA,此时栈顶是function类型,即AAA=function () end

    luaL_dostring(L, "print(AAA("123"))"),在lua中将参数123进栈

    lua_tostring(L, 1),在c#中将栈顶元素123转换为string用于操作,栈是这样的(从栈底到栈顶):123

    lua_pushstring(L, "Hello " + s),在c#中将返回值进栈,供lua使用,栈是这样的(从栈底到栈顶):123->Hello 123

    注意:

    1.lua调用c#,涉及到将c#方法的注册到lua中,对应上面的语句lua_pushstdcallcfunction和lua_setglobal,其中lua_pushstdcallcfunction的原型为:

    public static void lua_pushstdcallcfunction(IntPtr luaState, LuaCSFunction function);

    而LuaCSFunction的原型为:

    public delegate int LuaCSFunction(IntPtr luaState);

    即要注册的方法返回值必须为int(表示返回值的个数),参数必须为IntPtr(指针,指向lua状态机)

    2.每个注册的方法(如上面的SayHello)都有1个私有栈,并且第1个参数就在栈的1位置,第2个参数就在栈的2位置,以此类推

    所以上面的LuaDLL.lua_tostring(L, 1)拿到的是第1个参数

    3.如果注册的方法有返回值,则按照返回顺序依次入栈,最后一个返回值在栈的-1位置

    三.unity相关

    1.wrap文件

    经过上面lua调用c#的介绍,再来看生成的wrap文件,会发现很熟悉(下面以UnityEngine_GameObjectWrap为例):

  • 相关阅读:
    mac sourceTree 每次操作提示需要密码
    docker-compose.yml开机启动
    详解Oracle 21c 中的只读Oracle主⽬录特性 (ROOH)
    使用kubeadm一键部署kubernetes集群
    Ubuntu18.04 开机自启动(需要 sudo 权限)
    nginx加载vue3 打包后的静态文件
    使用Docker搭建Nextcloud SSL站点
    Docker+Selenium+TestNG+Maven+Jenkins环境搭建
    Windows Server 2016安装AD并开启SSL
    Centos 环境配置内网 Yum 源
  • 原文地址:https://www.cnblogs.com/lyh916/p/12234220.html
Copyright © 2011-2022 走看看