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

摘要:
使用系统;使用System.Collections。通用的使用系统。文本使用系统。反射使用System.Windows。形式;使用系统。IO;NamespaceReflectionLesson{/////<summary˃///反射类////使用反射来动态调用DLL类库。////publicclassReflectionClass{privatestringstrDllName=“”;privatestringestrLaName=“;privatestring[]strMetName=null;////构造函数/////<paramname=“DllName”>调用的DLL类库名称//class name called///调用的方法名(Array)publicReflectionLesson{//获取调用的DLL类库this.strClaName=ClaName;this.strDllName=DllName;this.strMetName=MetName;}//////通过反射动态调用DLL类库////publicvoidReflectionTest{Assemblyass;Typetype;objectobj;if{//获取并加载DLL类库ass=assembly.LoadFile中的程序集;//获取类类型:必须使用命名空间+类名type=ass.GetType;//获取类名:方法名MethodInfomethod1=type.GetMethod;MethodInfomethod2=type.Get方法;MethodInfomethod3=type.Get方法;//创建所获取类的实例。
最近由于业务要求,需要动态调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);
        }
    }
}

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

免责声明:文章转载自《利用C#的反射机制动态调用DLL类库》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇GDB 命令行调试之路(全 19)Java与flash的TCP通讯下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

ASP.NET Core 中间件(Middleware)(一)

本文主要目标:记录Middleware的运行原理流程,并绘制流程图。 目录结构: 1、运行环境 2、Demo实践 3、源码追踪 4、AspnetCore内置middleware 一、运行环境 Visual Studio Community 2019 版本 16.8.5 .Net Sdk Version: 5.0.103 二、Demo实践 讲解或学习一个东...

转载-&amp;gt;C#异常处理

C#异常处理 异常是在程序执行期间出现的问题。C# 中的异常是对程序运行时出现的特殊情况的一种响应,比如尝试除以零。 异常提供了一种把程序控制权从某个部分转移到另一个部分的方式。C# 异常处理时建立在四个关键词之上的:try、catch、finally和throw。 try:一个 try 块标识了一个将被激活的特定的异常的代码块。后跟一个或多个 cat...

SQLServer 的存储过程与java交互

一、   存储过程简介 Sql Server的存储过程是一个被命名的存储在服务器上的Transacation-Sql语句集合,是封装重复性工作的一种方法,它支持用户声明的变量、条件执行和其他强大的编程功能。 存储过程相对于其他的数据库访问方法有以下的优点:    (1)重复使用。存储过程可以重复使用,从而可以减少数据库开发人员的工作量。     (2)...

上手七牛云存储

早就听说过七牛云存储,终于有时间上手实践。 1、第一步,注册七牛账号,由于是测试,首先申请的是个人账号 2、注册成功之后,默认是体验账号,每月只有1G的空间容量及1G的下载流量       3、账号认证,认证成功之后将升级为标准账号,每月有10G的空间容量及20G的下载流量       虽然认证麻烦了些,但看得出来,七牛还是很良心的,这种免费套餐对于一...

获取DataTable中一列的数据

#region 获取合同号DataRow[] arrRow = new DataRow[ds.Rows.Count];int w = 0;foreach (DataRow row in ds.Rows){arrRow[w] = row;w++;}string[] ary = Array.ConvertAll(arrRow, r => r["cdon...

Java与flash的TCP通讯

flash代码: var mySocket:XMLSocket = new XMLSocket(); //本地地址,端口5000 mySocket.connect(”localhost”, 5000); //事件 mySocket.onConnect = function(myStatus) { if (myStatus) { trace(”连接成功!”...