Tag Archives: xLua

Xlua#: How to Call C

Call C in xlua#

1. Premise

The xlua framework is used here. You need to configure xlua in advance and set the loader path;

You can refer to the previous blog: xlua introduction;

//On the call side, all the lua code is written in the LuaCallCSharp.lua file
public class LuaCallCSharp1 : MonoBehaviour
{
    void Start()
    {
        XluaEnv.I.DoString("LuaCallCSharp");
    }

    private void OnDestroy()
    {
        XluaEnv.I.Free();
    }
}

2. Call c# class

Static class

public static class TestStatic
{
    public static void ShowName(string name, int id)
    {
        Debug.Log($"name:{name},id:{id}");
    }
}

--静态类
CS.TestStatic.ShowName("littlePerilla",1012);

Dynamic class

public class NPC
{
    public string name;
    public int attack;

    public NPC(string name,int attack)
    {
        this.name = name;
        this.attack = attack;
    }

    public int Hp { get; set; }

    public void Attack()
    {
        Debug.Log($"attack:{attack},Hp:{Hp}");
    }
}

--类对象
local hero = CS.NPC("Angel",100)
hero.Hp = 110
hero:Attack()

Call unity official API

--创建物体
local go = CS.UnityEngine.GameObject("LuaObj ")
--添加组件
go:AddComponent(typeof(CS.UnityEngine.BoxCollider))

Lua does not support generics. You need to write every possible overload where generics are used;

Call parent and child classes

public class Father
{
    public string name = "father";

    public virtual void Say()
    {
        Debug.Log($"{name}:我在被调用");
    }
}

public class Child :Father
{
    public string name = "child";

    public override void Say()
    {
        Debug.Log($"{name}:我在被调用");
    }
}

local father = CS.Father()
father:Say()

local child = CS.Child()
child:Say()

Class expansion method

The extended class must be a static class, and the class must have the attribute [luacallcsharp]; C# type expansion method;

It will be affected by xlua version and unity version, resulting in call failure. The official recommended version of xlua is 2017 (too outdated);

public class TestExtension
{
    public string Test1()
    {
        return "test";
    }
}

[LuaCallCSharp]
public static class MyExtension
{
    public static void Test2(this TestExtension obj)
    {
        Debug.Log("ExtensionFunc:"+ obj.Test1());
    }
}

local testEx = CS.TestExtension()

print(testEx:Test1())
testEx:Test2()

3. Call c# structure

Structures are similar to classes and have construction methods;

public struct TestStruct
{
    public int id;
    public string name;

    public void Output()
    {
        Debug.Log(id);
        Debug.Log(name);
    }
}

--结构体
local teststrut = CS.TestStruct()

teststrut.id = 12
teststrut.name = "littlePerilla"

teststrut:Output()

4. Call c# enumeration

Enumerate the userdate user-defined data types used;

public enum State
{
    idle = 0,
    walk,
    run,
    attack
}

--枚举使用的userdate自定义数据类型
local state = CS.State.idle

print(state)

--转换获得枚举
print(CS.State.__CastFrom(1))
print(CS.State.__CastFrom("run"))

5. Call the delegation in c#

Static delegate assignment call must be released;

Dynamic delegation is not necessary, but it is best to release it;

Make a null judgment before calling the delegate;

There is no + = or – = method in Lua. Multicast can only be realized through a = a + B;

public delegate void DelegateLua();

public class TestDelegate
{
    public static DelegateLua deStatic;

    public DelegateLua deDynamic;

    public static void Func()
    {
        Debug.Log("静态委托");
    }

    public void Func2()
    {
        Debug.Log("动态委托");
    }
}

--静态委托赋值调用必须释放
CS.TestDelegate.deStatic = CS.TestDelegate.Func
CS.TestDelegate.deStatic()
CS.TestDelegate.deStatic = nil

local func = function ()
	-- body
	print("lua函数替换委托")
end

--lua函数赋值委托
CS.TestDelegate.deStatic = func
--多播委托,确定deStatic不为空,lua没有+=和-=
if(CS.TestDelegate.deStatic ~= nil)then
	CS.TestDelegate.deStatic = CS.TestDelegate.deStatic + func
else 
	CS.TestDelegate.deStatic = func
end

--调用前判定不为空
if(CS.TestDelegate.deStatic ~= nil)then
	CS.TestDelegate.deStatic()
end

CS.TestDelegate.deStatic = nil
--动态委托
local test = CS.TestDelegate()

local func1 = function()
	print("动态委托调用")
end

test.deDynamic = func1
test.deDynamic()
test.deDynamic = nil

6. Call c# event

The call of events cannot be copied directly, but (“+”, function) must be used;

The event callback also needs to be released;

public delegate void EventLua();

public class TestEvent
{
    public event EventLua luaEvent1;
    
    public static event EventLua luaEvent2;

    public static void Func()
    {
        Debug.Log("静态事件");
    }

    public static void CallEvent2()
    {
        if (luaEvent2 != null)
            luaEvent2();
    }

    public void CallEvent1()
    {
        if (luaEvent1 != null)
            luaEvent1();
    }
}

--静态事件
CS.TestEvent.luaEvent2("+",CS.TestEvent.Func)
CS.TestEvent.CallEvent2()
CS.TestEvent.luaEvent2("-",CS.TestEvent.Func)


--动态事件
local test = CS.TestEvent()

local func = function ()
	print("动态事件")
end

test:luaEvent1("+",func)
test:CallEvent1()
test:luaEvent1("-",func)