• 利用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);
            }
        }
    }

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

  • 相关阅读:
    如何紧急恢复SQL Server主数据库
    合理利用SQL Server查询执行计划
    理解RAID的四种级别
    sp_spaceused 显示行数、保留的磁盘空间以及当前数据库中的表、索引视图
    修复数据库索引问题:理解填充因数设置
    SQL Server调整因子
    sqlservr 命令行启动
    DBA需要考虑备份相关问题
    BCP
    “tablediff ”命令行工具
  • 原文地址:https://www.cnblogs.com/vip-ygh/p/3581978.html
Copyright © 2020-2023  润新知