本文参考资料:
1. 《C#高级编程第六版》第十三章:反射
2. rcfalcon的CSDN Blog:《封装Lua for C#》http://www.2cto.com/kf/201204/127960.html
本文仅讨论什么是特性定制以及怎样将C#与LUA脚本配合起来形成我们的应用
using System;
using System.Text;
using System.Reflection;
namespace ConsoleApplication3
{
public class mainClass
{
static void Main(string[] args)
{
Console.WriteLine(GETMYNAME);
Console.Read();
}
[CGYClass("CaiGuangyue")]
public static string GETMYNAME
{
get
{
return "CGY’Name";
}
}
public string CGYComment;
}
[AttributeUsage(AttributeTargets.Property,AllowMultiple=false,Inherited=true)]
class CGYClassAttribute:Attribute
{
private string CGYName;
public CGYClassAttribute(string cgyName)
{
this.CGYName = cgyName;
}
public string GetCGYName()
{
return this.CGYName;
}
}
}
这是我写的一个测试例子.
.Net FrameWork允许用户定义自己的特性,如果我们将这些定制特性运用到我们的项目中,那么当我们开发可扩展应用时,即可加载插件或者模块,无疑是十分Happy的.
为什么要提到反射中的定制特性?
因为我们接下来的例子中即将用到特性定制,利用特性定制我们就可以很容易的封装我们自己的LUA应用,以方便我们在LUA 脚本中使用.
先来一个简单的例子:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.IO;
using System.Net;
using LuaInterface;
namespace LUATest
{
public partial class frmMain : Form
{
private Lua MyLua = new Lua();
private string FileName;
public frmMain()
{
InitializeComponent();
}
private void btnFileName_Click(object sender, EventArgs e)
{
OpenFileDialog ofg=new OpenFileDialog();
ofg.Filter = "LUA脚本文件(*.lua)|*.lua|所有文件(*.*)|*.*";
if (ofg.ShowDialog()==DialogResult.OK)
{
txtFileName.Text = ofg.FileName;
FileName = ofg.FileName;
StreamReader sr = new StreamReader(ofg.FileName,Encoding.Default);
txtFileContent.Text = sr.ReadToEnd();
sr.Close();
}
}
/// <summary>
/// LUA中要用到的Echo方法,目的是将LUA的执行结果msg添加到ListBox txtResult上
/// </summary>
/// <param name="msg">执行结果</param>
public void Echo(string msg)
{
txtResult.Items.Add(msg);
}
private void btnRun_Click(object sender, EventArgs e)
{
MyLua.RegisterFunction("Echo", this, this.GetType().GetMethod("Echo"));
MyLua.DoFile(FileName);
}
}
}
在这个简单的例子结束后,我们使用反射中的特性定制开始封装我们自己应用.
定制特性类:
using System;
using System.Collections.Generic;
using System.Text;
using System.Reflection;
namespace LUATest
{
/// <summary>
/// 特性类
/// </summary>
[AttributeUsage(AttributeTargets.Method,AllowMultiple=false,Inherited=false)]
class Lua_ClsAttribute:Attribute
{
private string _luaFuncName;
/// <summary>
/// 特性类构造函数
/// </summary>
public Lua_ClsAttribute(string luaFuncName)
{
this._luaFuncName = luaFuncName;
}
public string GetLuaFuncName()
{
return this._luaFuncName;
}
}
}
我们自己的LUA应用库:
using System;
using System.Collections.Generic;
using System.Text;
using System.Reflection;
using System.Windows;
using LuaInterface;
namespace LUATest
{
/// <summary>
/// 本类采集自rcfalcon的CSDN Blog:《封装Lua for C#》
/// URL:http://www.2cto.com/kf/201204/127960.html
/// </summary>
class LUAFrame
{
/// <summary>
/// Lua引擎
/// </summary>
private Lua pLuaVM = new Lua();//lua虚拟机
/// <summary>
/// 注册lua函数
/// </summary>
/// <param name="pLuaAPIClass">lua函数类</param>
public void BindLuaApiClass(Object pLuaAPIClass)
{
foreach (MethodInfo mInfo in pLuaAPIClass.GetType().GetMethods())
{
foreach (Attribute attr in Attribute.GetCustomAttributes(mInfo))
{
string LuaFunctionName = (attr as Lua_ClsAttribute).GetLuaFuncName();
pLuaVM.RegisterFunction(LuaFunctionName, pLuaAPIClass, mInfo);
}
}
}
/// <summary>
/// 执行lua脚本文件
/// </summary>
/// <param name="luaFileName">脚本文件名</param>
public void ExecuteFile(string luaFileName)
{
pLuaVM.DoFile(luaFileName);
}
/// <summary>
/// 执行lua脚本
/// </summary>
/// <param name="luaCommand">lua指令</param>
public void ExecuteString(string luaCommand)
{
pLuaVM.DoString(luaCommand);
}
}
}
紧接着.构造自己的应用与LUA的API类:
using System;
using System.Collections.Generic;
using System.Text;
using System.Net;
using System.IO;
namespace LUATest
{
class LUAAPI
{
frmMain fm=(frmMain)frmMain.ActiveForm;
/// <summary>
/// LUA中要用到的Echo方法,目的是将LUA的执行结果msg添加到ListBox txtResult上
/// </summary>
/// <param name="msg">执行结果</param>
[Lua_Cls("Echo")]
public void Echo(string msg)
{
fm.EchoResult(msg);
} }
}
接着我们来更改下自己的窗体类:
public partial class frmMain : Form
{
private string FileName;
public frmMain()
{
InitializeComponent();
}
private void btnFileName_Click(object sender, EventArgs e)
{
OpenFileDialog ofg=new OpenFileDialog();
ofg.Filter = "LUA脚本文件(*.lua)|*.lua|所有文件(*.*)|*.*";
if (ofg.ShowDialog()==DialogResult.OK)
{
txtFileName.Text = ofg.FileName;
FileName = ofg.FileName;
StreamReader sr = new StreamReader(ofg.FileName,Encoding.Default);
txtFileContent.Text = sr.ReadToEnd();
sr.Close();
}
}
public void EchoResult(string Msg)
{
txtResult.Items.Add(Msg);
}
private void btnRun_Click(object sender, EventArgs e)
{
LUAFrame lf = new LUAFrame();
lf.BindLuaApiClass(new LUAAPI());
lf.ExecuteFile(FileName);
}
}
LUA文件的内容继续保持不变,那么我就可以得到和刚才一样的输出结果.
联系客服