最近由于业务要求,需要动态调用DLL类库,所以研究了一下,感觉还好也不太难,今天就把自己理解的写了一个小例子(已经通过VS2005跑通),供大家一起研究和探讨,有理解不当的地方还请高手们多多指正,谢谢啦!
好,在这之前我先把反射所需要使用的几个类给大家列一下:
1、使用Assembly类定义和加载程序集,加载在程序集清单中列出模块,以及从此程序集中查找类型并创建该类型的实例。
2、使用MethodInfo了解方法的名称、返回类型、参数、访问修饰符(如pulic 或private)和实现详细信息(如abstract或virtual)等。使用Type的GetMethods或GetMethod方法来调用特定的方法。
一、创建用于反射调用的DLL
using System; using System.Collections.Generic; using System.Text; namespace RefDll { /// <summary> /// 创建需要被调用的DLL类库 /// </summary> public class RefTest { /// <summary> /// 求和方法 /// </summary> /// <param name="x">第一个值</param> /// <param name="y">第二个值</param> /// <param name="sum">结果(和)</param> public void TestSum(int x,int y,out int sum) { sum = 0; sum = x + y; } /// <summary> /// 求和方法 /// 第二种方式 /// </summary> /// <param name="x">第一个值</param> /// <param name="y">第二个值</param> /// <returns>结果(和)</returns> public int TestSumTwo(int x, int y) { return x + y; } /// <summary> /// 求和方法 /// 第三种方式 /// </summary> /// <param name="x">第一个值</param> /// <param name="y">第二个值</param> /// <param name="sum">结果(和)</param> public static void TestSumThree(int x, int y, out int sum) { sum = 0; sum = x + y; } } }
二、应用于反射的例子
注:可以创建一个控制台的工程。
using System; using System.Collections.Generic; using System.Text; using System.Reflection; using System.Windows.Forms; using System.IO; namespace ReflectionLesson { /// <summary> /// 反射类 /// 利用反射动态调用DLL类库。 /// </summary> public class ReflectionLesson { private string strDllName = ""; private string strClaName = ""; private string[] strMetName = null; /// <summary> /// 构造方法 /// </summary> /// <param name="DllName">调用的DLL类库名</param> /// <param name="ClaName">调用的类名</param> /// <param name="MetName">调用的方法名(数组)</param> public ReflectionLesson(string DllName, string ClaName, string[] MetName) { //获取调用的DLL类库 this.strClaName = ClaName; this.strDllName = DllName; this.strMetName = MetName; } /// <summary> /// 利用反射动态调用DLL类库 /// </summary> public void ReflectionTest(int x,int y) { Assembly ass; Type type; object obj; if (File.Exists(Application.StartupPath + "\" + this.strDllName + ".dll")) { //获取并加载DLL类库中的程序集 ass = Assembly.LoadFile(Application.StartupPath + "\" + this.strDllName + ".dll"); //获取类的类型:必须使用名称空间+类名称 type = ass.GetType(this.strDllName + "." + this.strClaName); //获取类的方法:方法名称 MethodInfo method1 = type.GetMethod(this.strMetName[0]); MethodInfo method2 = type.GetMethod(this.strMetName[1]); MethodInfo method3 = type.GetMethod(this.strMetName[2]); //对获取的类进行创建实例。//必须使用名称空间+类名称 obj = ass.CreateInstance(this.strDllName + "." + this.strClaName); //开始搜索方法 method1 = type.GetMethod(this.strMetName[0]);//方法的名称1 method2 = type.GetMethod(this.strMetName[1]);//方法的名称2 method3 = type.GetMethod(this.strMetName[2]);//方法的名称3 object[] parts = new object[3]; parts[0] = x; parts[1] = y; //方法的调用 //注:如果调用的DLL类库中方法是静态的,那么Invoke方法中第一个参数传值为NULL。 // 如果方法不是静态的,那么Invoke方法中第一个参数传值为 obj(上面那个被实例的对象) method1.Invoke(obj, parts); Console.WriteLine("调用的方法 " + this.strMetName[0] + ": " + x + " + " + y + " = " + parts[2]); int sum1 = (int)method2.Invoke(obj, new object[] { x + 10, y + 10 }); Console.WriteLine("调用的方法 " + this.strMetName[1] + ": " + (x + 10) + " + " + (y + 10) + " = " + sum1); object[] temParts = new object[3]; temParts[0] = x + 20; temParts[1] = y + 20; method3.Invoke(null, temParts); Console.WriteLine("调用的方法 " + this.strMetName[2] + ": " + temParts[0] + " + " + temParts[1] + " = " + temParts[2]); } } } }
在Main 函数中可以输入以下代码:
using System; using System.Collections.Generic; using System.Text; using System.Windows.Forms; namespace ReflectionLesson { class Program { static void Main(string[] args) { string dllname = "RefDll"; string claname ="RefTest"; string[] metname = new string[]{"TestSum","TestSumTwo","TestSumThree"}; ReflectionLesson refl = new ReflectionLesson(dllname, claname, metname); refl.ReflectionTest(100,200); } } }
好了。现在可以跑一下如何调用的了,大家可以设置在调试模式下进行阅读代码。