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

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

 

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

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

2、使MethodInfo了解方法名称、返回类型、参数、访问修饰符(如pulic 或private)实现详细信息(如abstract或virtual)等。使TypeGetMethods或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);

        }

    }

}

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

 

 

你可能感兴趣的:(反射机制)