利用C#的反射机制动态调用DLL类库

利用C#的反射机制动态调用DLL类库

 

最近由于业务要求,需要动态调用DLL类库,所以研究了一下,感觉还好也不太难,今天就把自己理解的写了一个小例子(已经通过VS2005跑通),供大家一起研究和探讨,有理解不当的地方还请高手们多多指正,谢谢啦!

好,在这之前我先把反射所需要使用的几个类给大家列一下:

1、使用Assembly类定义和加载程序集,加载在程序集清单中列出模块,以及从此程序集中查找类型并创建该类型的实例。

2、使用MethodInfo了解方法的名称、返回类型、参数、访问修饰符(如pulic 或private)和实现详细信息(如abstract或virtual)等。使用Type的GetMethods或GetMethod方法来调用特定的方法。

一、创建用于反射调用的DLL

 1 using System;
 2 using System.Collections.Generic;
 3 using System.Text;
 4 
 5 namespace RefDll
 6 {
 7     /// <summary>
 8     /// 创建需要被调用的DLL类库
 9     /// </summary>
10     public class RefTest
11     {
12         /// <summary>
13         /// 求和方法
14         /// </summary>
15         /// <param name="x">第一个值</param>
16         /// <param name="y">第二个值</param>
17         /// <param name="sum">结果(和)</param>
18         public void TestSum(int x,int y,out int sum)
19         {
20             sum = 0;
21             sum = x + y;
22         }
23 
24         /// <summary>
25         /// 求和方法
26         /// 第二种方式
27         /// </summary>
28         /// <param name="x">第一个值</param>
29         /// <param name="y">第二个值</param>
30         /// <returns>结果(和)</returns>
31         public int TestSumTwo(int x, int y)
32         {
33             return x + y;
34         }
35 
36         /// <summary>
37         /// 求和方法
38         /// 第三种方式
39         /// </summary>
40         /// <param name="x">第一个值</param>
41         /// <param name="y">第二个值</param>
42         /// <param name="sum">结果(和)</param>
43         public static void TestSumThree(int x, int y, out int sum)
44         {
45             sum = 0;
46             sum = x + y;
47         }
48 
49     }
50 }

二、应用于反射的例子

    注:可以创建一个控制台的工程。

 1  using System;
 2 using System.Collections.Generic;
 3 using System.Text;
 4 using System.Reflection;
 5 using System.Windows.Forms;
 6 using System.IO;
 7 
 8 namespace ReflectionLesson
 9 {
10     /// <summary>
11     /// 反射类
12     /// 利用反射动态调用DLL类库。
13     /// </summary>
14     public class ReflectionLesson
15     {
16         private string strDllName = "";
17         private string strClaName = "";
18         private string[] strMetName = null;
19         /// <summary>
20         /// 构造方法
21         /// </summary>
22         /// <param name="DllName">调用的DLL类库名</param>
23         /// <param name="ClaName">调用的类名</param>
24         /// <param name="MetName">调用的方法名(数组)</param>
25         public ReflectionLesson(string DllName, string ClaName, string[] MetName)
26         {
27             //获取调用的DLL类库
28             this.strClaName = ClaName;
29             this.strDllName = DllName;
30             this.strMetName = MetName;
31         }
32 
33         /// <summary>
34         /// 利用反射动态调用DLL类库
35         /// </summary>
36         public void ReflectionTest(int x,int y)
37         {
38             Assembly ass;
39             Type type;
40             object obj;
41             if (File.Exists(Application.StartupPath + "\\" + this.strDllName + ".dll"))
42             {
43                 //获取并加载DLL类库中的程序集
44                 ass = Assembly.LoadFile(Application.StartupPath + "\\" + this.strDllName + ".dll");
45 
46                 //获取类的类型:必须使用名称空间+类名称
47                 type = ass.GetType(this.strDllName + "." + this.strClaName);
48 
49                 //获取类的方法:方法名称
50                 MethodInfo method1 = type.GetMethod(this.strMetName[0]);
51                 MethodInfo method2 = type.GetMethod(this.strMetName[1]);
52                 MethodInfo method3 = type.GetMethod(this.strMetName[2]);
53 
54                 //对获取的类进行创建实例。//必须使用名称空间+类名称
55                 obj = ass.CreateInstance(this.strDllName + "." + this.strClaName);
56 
57                 //开始搜索方法
58                 method1 = type.GetMethod(this.strMetName[0]);//方法的名称1
59                 method2 = type.GetMethod(this.strMetName[1]);//方法的名称2
60                 method3 = type.GetMethod(this.strMetName[2]);//方法的名称3
61 
62                 object[] parts = new object[3];
63                 parts[0] = x;
64                 parts[1] = y;
65 
66                 //方法的调用
67                 //注:如果调用的DLL类库中方法是静态的,那么Invoke方法中第一个参数传值为NULL。
68                 //    如果方法不是静态的,那么Invoke方法中第一个参数传值为 obj(上面那个被实例的对象)
69         method1.Invoke(obj, parts);
70         Console.WriteLine("调用的方法 " + this.strMetName[0] + ": " + x + " + " + y + " = " + parts[2]);
71 
72            int sum1 = (int)method2.Invoke(obj, new object[] { x + 10, y + 10 });
73            Console.WriteLine("调用的方法 " + this.strMetName[1] + ": " + (x + 10) + " + " + (y + 10) + " = " + sum1);
74 
75 
76                 object[] temParts = new object[3];
77                 temParts[0] = x + 20;
78                 temParts[1] = y + 20;
79                 method3.Invoke(null, temParts);
80                 Console.WriteLine("调用的方法 " + this.strMetName[2] + ": " + temParts[0] + " + " + temParts[1] + " = " + temParts[2]);
81             }
82         }
83     }
84 }

在Main 函数中可以输入以下代码:

 1   using System;
 2 using System.Collections.Generic;
 3 using System.Text;
 4 using System.Windows.Forms;
 5 namespace ReflectionLesson
 6 {
 7     class Program
 8     {
 9         static void Main(string[] args)
10         {
11             string dllname = "RefDll";
12             string claname ="RefTest";
13             string[] metname = new string[]{"TestSum","TestSumTwo","TestSumThree"};
14             ReflectionLesson refl = new ReflectionLesson(dllname, claname, metname);
15             refl.ReflectionTest(100,200);
16         }
17     }
18 }

好了。现在可以跑一下如何调用的了,大家可以设置在调试模式下进行阅读代码。

 

 

=========================================================================

 

反射的作用: 1. 可以使用反射动态地创建类型的实例,将类型绑定到现有对象,或从现有对象中获取类型 2. 应用程序需要在运行时从某个特定的程序集中载入一个特定的类型,以便实现某个任务时可以用到反射。 3. 反射主要应用与类库,这些类库需要知道一个类型的定义,以便提供更多的功能。

 

1 需要反射的DLL

 1 using System;
 2 namespace Webtest
 3 {
 4 public class ReflectTest
 5 {
 6 public ReflectTest(){}
 7 public string WriteString(string s)
 8 {
 9    return "欢迎您," + s;
10 }
11 //静态函数
12 public static string WriteName(string s)
13 {
14 return "欢迎您光临," + s;
15 }
16 //不带参数的函数
17 public string WriteNoPara()
18 {
19 return "您使用的是无参数方法";
20 }
21 }
22 }

应用于反射的例子-在ASPNET页面中加入以下函数:

 1 public void test1()
 2 {
 3 System.Reflection.Assembly ass;
 4 Type type ;
 5 object obj;
 6 try
 7 {
 8 ass = System.Reflection.Assembly.LoadFile(@"d:\TestReflect.dll");//要绝对路径
 9 type = ass.GetType("Webtest.ReflectTest");//必须使用 名称空间+类名称
10 System.Reflection.MethodInfo method = type.GetMethod("WriteString");//方法的名称
11 obj = ass.CreateInstance("Webtest.ReflectTest");//必须使用名称空间+类名称
12 string s = (string)method.Invoke(obj,new string[]{"jianglijun"}); // 实例方法的调用
13 或:string s = (string)method.Invoke(obj,Object[] parametors = new Object[]{"param"}); 
14 Response.Write(s+"<br>");
15 method = type.GetMethod("WriteName");//方法的名称
16 s = (string)method.Invoke(null,new string[]{"jianglijun"}); // 静态方法的调用
17 Response.Write(s+"<br>");
18 
19 method = type.GetMethod("WriteNoPara");//无参数的实例方法
20 s = (string)method.Invoke(obj,null);
21 Response.Write(s+"<br>");
22 method = null;
23 }
24 catch(Exception ex)
25 {
26 Response.Write(ex+"<br>");
27 }
28 finally
29 {
30 ass = null;
31 type = null;
32 obj = null;
33 }
34 } 

 

posted @ 2012-07-08 22:32  Lyghost  阅读(943)  评论(0编辑  收藏  举报