C#主动发起对 Lua 数据结构的访问。
1 获取一个全局基本数据类型
访问 LuaEnv.Global 就可以了,上面有个模版 Get 方法,可指定返回的类型。
luaenv.Global.Get(“a”)
luaenv.Global.Get(“b”)
luaenv.Global.Get(“c”)

新建文本文档 Test004.lua.txt
内容为

a=100
b="哈哈哈哈"
c=false
print("66")
void Start()
{
LuaEnv env=new LuaEnv();
env.DoString("require [[Test004]]");
int a=env.Global.Get<int>("a");
string b = env.Global.Get<string>("b");
bool c = env.Global.Get<bool>("c");
Debug.Log(a+":"+b+":"+c);
env.Dispose();
}

04C#访问Lua之访问Lua中的全局变量_lua

2:访问一个全局的 table
也是用上面的 Get 方法,那类型要指定成啥呢?
1、映射到普通 class 或 struct
定义一个 class,有对应于 table 的字段的 public 属性,而且有无参数构造函数即可,比
如对于{f1 = 100, f2 = 100}可以定义一个包含 public int f1;public int f2;的 class。
这种方式下 xLua 会帮你 new 一个实例,并把对应的字段赋值过去。
table 的属性可以多于或者少于 class 的属性。可以嵌套其它复杂类型。
要注意的是,这个过程是值拷贝,如果 class 比较复杂代价会比较大。而且修改 class
的字段值不会同步到 table,反过来也不会。
这个功能可以通过把类型加到 GCOptimize 生成降低开销,详细可参见配置介绍文档。
那有没有引用方式的映射呢?有,下面这个就是:
lua脚本创建table

tab={name="棠下村";age=100}
print(tab.name)
print(tab.age)

解析

public class person
{
public string name;
public int age;
}
person person=env.Global.Get<person>("tab");
Debug.Log(person.name+" "+person.age);

04C#访问Lua之访问Lua中的全局变量_字段_02


3、映射到一个 interface

这种方式依赖于生成代码(如果没生成代码会抛 InvalidCastException 异常),代码生

成器会生成这个 interface 的实例,如果 get 一个属性,生成代码会 get 对应的 table 字段,如

果 set 属性也会设置对应的字段。甚至可以通过 interface 的方法访问 lua 的函数。

lua代码

tab={name="棠下村";age=100}
print(tab.name)
print(tab.age)
[CSharpCallLua]
interface IPerson
{
string name { get; set; }
int age { get; set; }
}
IPerson iPerson=env.Global.Get<IPerson>("tab");
Debug.Log(iPerson.name + " " + iPerson.age);

04C#访问Lua之访问Lua中的全局变量_字段_03

可以改变lua文件中table 字段的值

iPerson.name = "黑花生";
env.DoString("print(tab.name)");

04C#访问Lua之访问Lua中的全局变量_字段_04

访问lua中的方法

tab={name="棠下村";age=100;
eat=function(self,a,b)
print(a+b)
end
}
function tab:test(a,b)
return a*b
end
iPerson.eat(10,100);
Debug.Log(iPerson.test(50,20));

04C#访问Lua之访问Lua中的全局变量_c#_05

4、更轻量级的 by value 方式:映射到 Dictionary<>,List<>
不想定义 class 或者 interface 的话,可以考虑用这个,前提 table 下 key 和 value 的类型
都是一致的。
lua脚本

tab={name="棠下村";age=100;10,20,100,false,
eat=function(self,a,b)
print(a+b)
end
}

C#

Dictionary<string, object> dictionary = env.Global.Get<Dictionary<string, object>>("tab");
foreach (var item in dictionary)
{
Debug.Log(item.Key + ":" + item.Value);
}

04C#访问Lua之访问Lua中的全局变量_c#_06

List<object> list = env.Global.Get<List<object>>("tab");
foreach (var item in list)
{
Debug.Log(item);
}

04C#访问Lua之访问Lua中的全局变量_c#_07

5、另外一种 by ref 方式:映射到 LuaTable 类
这种方式好处是不需要生成代码,但也有一些问题,比如慢,比方式 2 要慢一个数量级,
比如没有类型检查。

LuaTable luaTable=env.Global.Get<LuaTable>("tab");
Debug.Log(luaTable.Get<string>("name"));
Debug.Log(luaTable.Get<int>("age"));

04C#访问Lua之访问Lua中的全局变量_字段_08