博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
08.XLua Lua访问C#中的方法
阅读量:6674 次
发布时间:2019-06-25

本文共 5472 字,大约阅读时间需要 18 分钟。

01.操作符重载和函数重载

C#中定义的操作符重载和函数重载在Lua中基本上能够使用,不过需要注意的是由于Lua中表示数值的类型只有一种(number),所以C#中对于数值类型之间的重载是不能够正确的识别的,通常只会调用类型符合的重载函数列表中先定义的函数

[LuaCallCSharp]public class Overload{
public int Add(int num1, int num2) {
Debug.Log("Add-int"); return num1 + num2; } public float Add(float num1, float num2) {
Debug.Log("Add-float"); return num1 + num2; } public string Add(string num1, string num2) {
Debug.Log("Add-string"); return num1 + num2; }}
local Overload=CS.Overload--获取一个类的映射local overload=CS.Overload()--实例化一个类print(overload:Add(1,2));print(overload:Add(1.5,2.1));print(overload:Add("22","22"));

在这里插入图片描述

由于在Lua中只有一种数值类型(number),所以参数为int和float类型的Add函数都满足要求,这个时候会调用先定义的重载函数,也就是重载为int类型的Add
当先定义参数float类型后定义int类型的Add函数时,Lua代码调用就是参数类型为float的Add函数了

02.可变参数与默认参数

在Lua中调用它们的时候,参数的规则与C#中相同
对于C#的如下方法:
void VariableParamsFunc(int a, params string[] strs)
可以在lua里头这样调用:
testobj:VariableParamsFunc(5, ‘hello’, ‘john’)

public void DefaultParam(int arg0, string arg1 = "1", int arg2 = 2)    {
Debug.Log("arg0:" + arg0); Debug.Log("arg1:" + arg1); Debug.Log("arg2:" + arg2); } public void VariableParam(int arg0, params string[] args) {
Debug.Log("arg0:" + arg0); Debug.Log(args.Length); foreach (string arg in args) {
Debug.Log(arg + " "); } }
local Overload=CS.Overload--获取一个类的映射local overload=CS.Overload()--实例化一个类overload:VariableParam(10,"1", "2", "3", "4");overload:DefaultParam(1);

在这里插入图片描述

03.访问C#枚举
枚举值就像枚举类型下的静态属性一样。
testobj:EnumTestFunc(CS.Tutorial.TestEnum.E1)
上面的EnumTestFunc函数参数是Tutorial.TestEnum类型的
另外,如果枚举类加入到生成代码的话,枚举类将支持__CastFrom方法,可以实现从一个整数或者字符串到枚举值的转换,例如:
CS.Tutorial.TestEnum.__CastFrom(1)
CS.Tutorial.TestEnum.__CastFrom(‘E1’)

在Lua中有以下五种方法可以访问到枚举变量:

1当作普通的静态属性访问
2使用__CastFrom函数,从枚举值对应的数值做类型转换
3使用__CastFrom函数,从枚举值对应的字符串做类型转换
4直接传入枚举值对应的数值
5直接传入枚举值对应的字符串

[LuaCallCSharp]public enum Language{
C_PLUS_PLUS, C_SHARP}[LuaCallCSharp]public class EnumParam{
public void PrintEnum(Language language) {
switch(language){
case Language.C_PLUS_PLUS: Debug.Log("C++"); break; case Language.C_SHARP: Debug.Log("C#"); break; } }}
--访问枚举local enumParam=CS.EnumParam();local Language=CS.Language;--当作普通的静态属性访问enumParam:PrintEnum(Language.C_PLUS_PLUS);--直接传入枚举值对应的字符串enumParam:PrintEnum("C_SHARP")--直接传入枚举值对应的数值enumParam:PrintEnum(1);--使用__CastFrom函数,从枚举值对应的数值做类型转换enumParam:PrintEnum(Language.__CastFrom("C_PLUS_PLUS"));--使用__CastFrom函数,从枚举值对应的数值做类型转换enumParam:PrintEnum(Language.__CastFrom(1));

在这里插入图片描述

04.
访问C#委托
delegate使用(调用,+,-)
C#的delegate调用:和调用普通lua函数一样
+操作符:对应C#的+操作符,把两个调用串成一个调用链,右操作数可以是同类型的C# delegate或者是lua函数。
-操作符:和+相反,把一个delegate从调用链中移除。
Ps:delegate属性可以用一个luafunction来赋值。

[LuaCallCSharp]class DelegateClass{
public delegate void ActionString(string arg); public ActionString action = (arg) => {
Debug.Log("action:" + arg); }; public ActionString actionString1 = (arg) => {
Debug.Log("actionString1:" + arg); }; public ActionString actionString2 = (arg) => {
Debug.Log("actionString2:" + arg); };}
--访问委托local delegateClass=CS.DelegateClass();--使用delegateClass类的对象访问委托变量actionlocal action1=delegateClass.action;action1("hi-1");--由于在Lua中没有"+="和"-="操作符,在增加委托链的时候只能使用"+"和"-"操作符action1=action1+delegateClass.actionString1+delegateClass.actionString2;action1("hi-2");action1=action1-delegateClass.actionString2;action1("hi-3");

在这里插入图片描述

在使用Lua代码访问C#委托时需要注意,访问委托类型的方式与访问静态变量的方式相同,访问(静态/非静态)委托的变量的方式与访问(静态/非静态)成员变量的方式相同

--使用DelegateClass类访问委托类型ActionString,--定义一个ActionString类型的委托变量action2local DelegateClass=CS.DelegateClass;local delegateClass=CS.DelegateClass();---此时action2的值为nillocal action2=DelegateClass.ActionString;action2=delegateClass.actionString1;action2("hi-4");action2=action2+delegateClass.actionString2;action2("hi-5");

在这里插入图片描述

05.访问C#事件
比如testobj里头有个事件定义是这样:public event Action TestEvent;
增加事件回调
testobj:TestEvent(’+’, lua_event_callback)
移除事件回调
testobj:TestEvent(’-’, lua_event_callback)

在访问C#事件的时候需要生成代码,所以必须要为事件的委托类型加上一个Attribute:[CSharpCallLua],关于为什么这里需要加[CSharpCallLua]而不是[LuaCallCSharp],在xLua的github主页的FAQ上作者是这么解释的:

LuaCallCSharp以及CSharpCallLua两种生成各在什么场景下用?

看调用者和被调用者,比如要在lua调用C#的GameObject.Find函数,或者调用gameobject的实例方法,属性等,GameObject类要加LuaCallSharp,而想把一个lua函数挂到UI回调,这是调用者是C#,被调用的是一个lua函数,所以回调声明的delegate要加CSharpCallLua。
有时会比较迷惑人,比如List.Find(Predicate match)的调用,List当然是加LuaCallSharp,而Predicate却要加CSharpCallLua,因为match的调用者在C#,被调用的是一个lua函数。
更无脑一点的方式是看到“This delegate/interface must add to CSharpCallLua : XXX”,就把XXX加到CSharpCallLua即可。

[LuaCallCSharp]class EventClass{
//在访问C#事件的时候需要生成代码 //所以必须要为事件的委托类型加上一个Attribute:[CSharpCallLua], [CSharpCallLua] public delegate void EventAction(); public event EventAction Events; public EventAction action1 = () => {
Debug.Log("action1"); }; public EventAction action2 = () => {
Debug.Log("action2"); }; public void TriggerEvent() {
Events(); }}

在添加事件的时候,既可以使用C#中的委托变量,也可以使用Lua中的函数

同时在添加和移除事件的时候应该使用以下的方式

object:event("+", delegate)

object:event("-", delegate)

function lua_action()    print("lua_action:")endlocal eventClass=CS.EventClass();eventClass:Events("+",lua_action);eventClass:Events("+",eventClass.action1);eventClass:Events("+",eventClass.action2);eventClass:TriggerEvent();

在这里插入图片描述

转载地址:http://nfrxo.baihongyu.com/

你可能感兴趣的文章
阿里张勇:数据驱动的透明是平台治理的基础
查看>>
ActiveMQ - JMS,Transport,Persistence
查看>>
互联网大数据支撑生态银行建设
查看>>
视频会议系统迎来第四次浪潮
查看>>
报告显示:被调研中国企业超85%已从数字转型中获得回报
查看>>
东方日升拉美光伏电站项目 将进入首期施工
查看>>
软件探索性测试 笔记二
查看>>
将来也不会被破译的分布式存储系统
查看>>
光伏电站或成辅助服务市场“输家”
查看>>
今年光伏“领跑者”计划将升级扩围
查看>>
Java程序运行超时后退出或进行其他操作的实现
查看>>
手把手教你启用RemoteFX以及Hyper-V GPU卸载
查看>>
《交互式程序设计 第2版》一3.10 更进一步
查看>>
英伟达发布Tesla P4&P40两款基于Pascal架构的深度学习芯片
查看>>
《ANSYS Workbench有限元分析实例详解(静力学)》——2.5 Windows界面相应操作
查看>>
《代码整洁之道:程序员的职业素养》一一1.3 首先,不行损害之事
查看>>
intellij 创建java web项目(maven管理的SSH)
查看>>
spring-java项目中连接redis数据库
查看>>
UML介绍--用例图
查看>>
阿里云DTS VS MySQLdump
查看>>