XLua框架学习(二)C#访问Lua中的变量以及函数

本文详细介绍了如何在C#中访问Lua脚本中的变量和表对象,包括by-value和by-ref两种方式,以及利用Dictionary<>, List<>和LuaTable类的不同映射方法。同时,提到了不同映射方式的性能和效果,如值传递与引用传递的区别,以及使用LuaTable类的优缺点。" 106628211,9263738,Java设计规约:Spec规范详解,"['Java开发', '编程规约', '函数设计']

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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();
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值