XLUA學習--C#訪問Lua全局函數

上一篇講到了通過接口的形式,可以訪問表內部的函數,那如果這個方法是一個全局的函數,就是這篇博客要講解的。

先上Lua中的代碼。

function TestOne()

print('no parm')
end


function TestTwo(a,b)
print(a,b)
end

function TestThree(a,b)
return a+b
end

function TestFour(a,b)
return a+b,a,b
end

上面有四個函數,分別爲沒有參數,帶參數,有返回值,有多個返回值這4種情況。

還是用LuaEnv.Global.Get<T>方法來實現。Lua中對應的函數,可以通過C#種的事件Action和委託delegate來實現。

1.無參數的調用

LuaEnv env = new LuaEnv();
env.DoString("require 'CSharpCallLua' ");
Action ac1=env.Global.Get<Action>("TestOne");
ac1();

2.帶參數的調用

接下來的幾種,都需要在方法前加上   [CSharpCallLua],如果不加的話,會報如下錯誤。

稍後再分析[CSharpCallLua]這句話到底起什麼樣的一個作用。

這裏不能再用Action去接收。而需要去委託,具體什麼原因還真不敢下結論。個人感覺[CSharpCallLua]定義的,是一個類型。比如上一篇博客說到的接口類,和現在用委託自定義的一種類型。先上錯誤的寫法。

    [CSharpCallLua]
    private Action<int, int> ac1;
    ac1 = env.Global.Get<Action<int, int>>("TestTwo");

再上正確的寫法

    [CSharpCallLua]
    delegate void AC2(int a,int b);
    AC2 ac2 = env.Global.Get<AC2>("TestTwo");
    ac2(2,5);


3.帶返回值的調用

和上面委託就沒啥區別了,也是上一個正確寫法和錯誤寫法

錯誤寫法

[CSharpCallLua]
private Func<int, int, int> ac3;

int res=ac3(2,5);

這裏Func的用法如果不會就去自行解決好了。

正確寫法

    [CSharpCallLua]
    delegate int AC3(int a, int b);
    AC3 ac3= env.Global.Get<AC3>("compare");
     int v = ac3(2, 3);

4.帶多個返回值的調用

Lua中支持多個返回值的回調,但C#沒這麼一說。這時候就可以在上面帶一個返回值的寫法基礎上通過ref,out形式獲取別的返回值。

    [CSharpCallLua]
    delegate int AC4(int a, int b,out int c,out int d);
    AC4 ac4=env.Global.Get<AC4>("TestFour");
    int res1;
    int res2;
    ac4(2,3,out res1,out re2);

當然這裏也可以用ref來實現,就不說了。

!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

接下來寫兩個過程中發現的需要注意的問題

1.在調用LuaEnv.Dispose()之前,要把所有訪問過程中生成的函數置爲空,否則會報無法釋放的錯誤。

需要加入ac1=null之後再去釋放。

2.就是  [CSharpCallLua]這個到底起的什麼作用了,在我研究過程中發現,比如上述2帶參數的調用。

我直接通過錯誤寫法,下面簡稱T1
Action<int, int> ac1 = env.Global.Get<Action<int, int>>("TestTwo");

是不行的,但是!!!如果我上面寫了正確方法:簡稱T2

    [CSharpCallLua]
    delegate void AC2(int a,int b);

而我並不去通過AC2去生成新的方法實例,只是把它寫那兒,然後再通過T1寫法去寫代碼,竟然是可以走通的。

剛開始懷疑是在在類初始化時做的手腳。我把T1放在了Awake裏,還是可以走通的。個人感覺,問題出在委託delegate 本身和Action之間的關係。Action和Func,本來就屬於U3D對delegate委託的一種封裝,所以當本身將T2前加了[CSharpCallLua]的時候,它就等同於給Action<int,int>類型的方法加上了[CSharpCallLua]。好吧,我也只能說個人猜測了,原理到底是啥,我不敢下結論,如果有大神看到這裏,也可以幫我分析解決下,個人覺得後者可能性非常大。

這塊兒爲什麼對於帶參數的委託需要自定義,而不能用Action和Func暫時還不太清楚。也希望看到的朋友能幫忙解釋一下。

5.通過Luafunction調用方法

它的參數,以及返回值都是object[]類型的,可以傳遞很多個。但和上面委託的方式相比,缺點就在於運行消耗較大,有點在於不需要像上面那樣自己定義。不過貌似XLUA不建議我們用這個。

  LuaFunction lf = env.Global.Get<LuaFunction>("compare1");
        lf.Call();

引用文檔裏的話,如果lua的實現的部分都以delegate和interface的方式提供,使用方可以完全和xLua解耦:由一個專門的模塊負責xlua的初始化以及delegate、interface的映射,然後把這些delegate和interface設置到要用到它們的地方。也就是表,建議用映射,方法,建議用delegate.

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章