C#访问Lua中的变量脚本
1.访问lua中的基础变量
CSharpCallLua.lua脚本
a = 100
str = "hu"
isDie = false
c#访问lua中的变量
using XLua;
LuaEnv luaEnv = new LuaEnv();
luaEnv.DoString("require 'CSharpCallLua'");//需要先将lua脚本加载进来
int a = luaEnv.Global.Get<int>("a")//获取lua中全局变量a
string str = luaEnv.Global.Get<string>("str")//获取lua中全局变量str
bool isDie = luaEnv.Global.Get<bool>("isDie")//获取lua中全局变量isDie
luaEnv.Dispose();
注意:映射的值必须一一对应,若lua中是一个小数,则只能映射成float或double,若映射成int则值为初始值0
2.访问lua中的表对象
1.by-value方式,通过类映射
CSharpCallLua.lua脚本
person = {
name = "hu" , age=100 , 12,2,2,2
eat = function()
print("eating")
end
c#访问lua中的变量
using XLua;
class Person //类名不需要相同,主要是数据
//注意必须变量名相同,且类型相同,若lua中变量存在C#中没有的,也没有关系,只是无法映射过来
//若类中存在lua表中不存在的变量,则初始化为默认值
{
public string name;
public int age;
}
LuaEnv luaEnv = new LuaEnv();
luaEnv.DoString("require 'CSharpCallLua'");//需要先将lua脚本加载进来
Person p = luaEnv.Global.Get<Person>("person");
print(p.name +"-" +p.age); //hu-100
p.name = "li"
luaEnv.DoString("print(person.name)") //hu
luaEnv.Dispose();
注意:类映射的话是一种值传递,因此在C#中改变对象的值不会影响lua中的表
这种方式比较耗费性能,因为需要new对象还需要拷贝对象值
1.by-ref方式,通过接口映射
CSharpCallLua.lua脚本
person = {
name = "hu" , age=100 , 12,2,2,2
eat = function()
print("eating")
end
using XLua;
[CSharpCallLua] //必须要加上这个特性
interface IPerson
{
public string name;
public int age;
}
LuaEnv luaEnv = new LuaEnv();
luaEnv.DoString("require 'CSharpCallLua'");//需要先将lua脚本加载进来
IPerson p = luaEnv.Global.Get<IPerson>("person");
print(p.name +"-" +p.age); //hu-100
p.name = "li"
luaEnv.DoString("print(person.name)") //li
luaEnv.Dispose();
映射lua表中的函数
person = {
eat = function()
print("eating")
end
add = function(self,a,b)
print(a+b)
end
using XLua;
[CSharpCallLua]
interface IPerson
{
void eat();
void add(int a ,int b);
}
LuaEnv luaEnv = new LuaEnv();
luaEnv.DoString("require 'CSharpCallLua'");//需要先将lua脚本加载进来
IPerson p = luaEnv.Global.Get<IPerson>("person");
p.eat(); //eating
p.add(12,34) //46
luaEnv.Dispose();
因为C#调用成员函数时,会默认第一个参数是对象本身,因此lua定义函数时,要默认第一个多传一个参数,可以写成这种形式
person = {
eat = function()
print("eating")
end
}
function person::add(a,b)
print(a+b)
end
注意:接口传递的话是一种引用传递,在C#中思考会影响lua中的表值
3.更轻量级的by-value方式,映射到Dictionary<>,List<>
CSharpCallLua.lua脚本
person = {
name = "hu" , age=100 , 12,2,2,2
eat = function(self ,a,b)
print(a+b)
end
映射到Dictionary<>
using XLua;
LuaEnv luaEnv = new LuaEnv();
luaEnv.DoString("require 'CSharpCallLua'");//需要先将lua脚本加载进来
Dictionary<string, object> dict= luaEnv.Global.Get<Dictionary<string ,object>>("person");
foreach(string key in dict.Keys)
{
print(key +"-" +dict[key]);
}
//age-100
//name-hu
//eat-function:11
luaEnv.Dispose();
用Dictionary接收,没有key的元素无法映射过来
映射到List<>
using XLua;
LuaEnv luaEnv = new LuaEnv();
luaEnv.DoString("require 'CSharpCallLua'");//需要先将lua脚本加载进来
List<object> list= luaEnv.Global.Get<List<object>>("person");
foreach(object o in list)
{
print(o);
}
//2
//2
//2
//12
luaEnv.Dispose();
用List接收,只能映射过来没有键的变量
4.by-ref方式,映射到LuaTable类
优点:不需要生成代码
缺点:很慢,比方式2要慢一个数量级,而且没有类型检查
因此不推荐使用
using XLua;
LuaEnv luaEnv = new LuaEnv();
luaEnv.DoString("require 'CSharpCallLua'");//需要先将lua脚本加载进来
LuaTable tab = luaEnv.Global.Get<LuaTable>("person");
print(tab.Get<string>("name")); //hu
print(tab.Get<int>("age"));//100
luaEnv.Dispose();