本文為 csdn rcfalcon 原創,轉載請標明出處。
作者:rcfalcon
原文:http://blog.csdn.net/rcfalcon/article/details/5583095
為了搞懂LUA在我們的GDEX中到底怎麼用,我決定研究一下如何比較好的在WPF裡封裝一個基於lua的APP framework。
今天先對Lua for C#進行了一次簡單的封裝。
在C#下用過Lua的人都知道,用C#實現一個函數之後和LUA綁定,需要用到Lua類的RegisterFunction方法。
在函數很少的情況下很好用,但是若需要綁定C#裡成百上千個函數,則麻煩了,添加一個函數,至少每次需要修改兩個地方:函數實現,函數綁定(RegisterFunction)。並且如果在lua中綁定的名字和C#中不一樣,則更麻煩,還需要維護一個函數映射。
今天翻了一下google,翻出GameDev.net上一篇老外的文章,叫《Using Lua with C#》,看了一下,它的方法不錯。(改天考慮翻譯這篇文章),不過他的範例程式碼實在是太太太冗長了,大部分是產生函數介紹和函數協助文檔等,直接忽略。把它最核心的東西拿過來,然後自己封裝了一下,用起來感覺不錯。
基本思想是,使用C#的Attribute來標記函數,實現自動綁定。
核心部分代碼如下(LuaFramework.cs):
using System;<br />using System.Collections.Generic;<br />using System.Linq;<br />using System.Text;<br />using System.Windows;<br />using System.Reflection;<br />using LuaInterface;</p><p>namespace WPFLuaFramework<br />{<br /> /// <summary><br /> /// Lua函數描述屬性類別<br /> /// </summary><br /> public class LuaFunction : Attribute<br /> {<br /> private String FunctionName;</p><p> public LuaFunction(String strFuncName)<br /> {<br /> FunctionName = strFuncName;<br /> }</p><p> public String getFuncName()<br /> {<br /> return FunctionName;<br /> }<br /> }</p><p> /// <summary><br /> /// Lua引擎<br /> /// </summary><br /> class LuaFramework<br /> {<br /> private Lua pLuaVM = new Lua();//lua虛擬機器</p><p> /// <summary><br /> /// 註冊lua函數<br /> /// </summary><br /> /// <param name="pLuaAPIClass">lua函數類</param><br /> public void BindLuaApiClass( Object pLuaAPIClass )<br /> {<br /> foreach (MethodInfo mInfo in pLuaAPIClass.GetType().GetMethods())<br /> {<br /> foreach (Attribute attr in Attribute.GetCustomAttributes(mInfo))<br /> {<br /> string LuaFunctionName = (attr as LuaFunction).getFuncName();<br /> pLuaVM.RegisterFunction(LuaFunctionName, pLuaAPIClass, mInfo);<br /> }<br /> }<br /> }</p><p> /// <summary><br /> /// 執行lua指令檔<br /> /// </summary><br /> /// <param name="luaFileName">指令檔名</param><br /> public void ExecuteFile(string luaFileName)<br /> {<br /> try<br /> {<br /> pLuaVM.DoFile(luaFileName);<br /> }<br /> catch (Exception e)<br /> {<br /> MessageBox.Show(e.ToString());<br /> }<br /> }</p><p> /// <summary><br /> /// 執行lua指令碼<br /> /// </summary><br /> /// <param name="luaCommand">lua指令</param><br /> public void ExecuteString(string luaCommand)<br /> {<br /> try<br /> {<br /> pLuaVM.DoString(luaCommand);<br /> }<br /> catch (Exception e)<br /> {<br /> MessageBox.Show(e.ToString());<br /> }<br /> }<br /> }<br />}<br />
我的LUA API類如下,用於實現C# for lua的函數(LuaAPI.cs)
using System;<br />using System.Collections.Generic;<br />using System.Linq;<br />using System.Text;<br />using System.Windows;</p><p>namespace WPFLuaFramework<br />{<br /> class LuaAPI<br /> {<br /> [LuaFunction("lua1")]<br /> public void a1()<br /> {<br /> MessageBox.Show("a1 called");<br /> }</p><p> [LuaFunction("lua2")]<br /> public int a2()<br /> {<br /> MessageBox.Show("a2 called");<br /> return 0;<br /> }</p><p> [LuaFunction("lua3")]<br /> public void a3(string s)<br /> {<br /> MessageBox.Show("a3 called");<br /> }<br /> }<br />}<br />
最後看調用代碼,是不是很簡單
LuaFramework test = new LuaFramework();<br />test.BindLuaApiClass(new LuaAPI());<br />test.ExecuteFile("test.lua");<br />test.ExecuteString("lua1()");
LUA代碼如下
lua1();
lua2();
lua3("test");
放到.NetFramework 4.0裡 需要在
public void BindLuaApiClass( Object pLuaAPIClass ) { foreach (MethodInfo mInfo in pLuaAPIClass.GetType().GetMethods()) { foreach (Attribute attr in Attribute.GetCustomAttributes(mInfo)) { string LuaFunctionName = (attr as LuaFunction).getFuncName(); pLuaVM.RegisterFunction(LuaFunctionName, pLuaAPIClass, mInfo); } } }
裡 加一句 判斷
if(attr is LuaFunction)