C# 运行时调用dll、dll中对象、对象中方法等

//dll

namespace Dynamic_linking
{
    public partial class ShowErrorForm : Form
    {
        public ShowErrorForm()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            MessageBox.Show("It is children!");
        }
        public int Add(int x, int y)
        {
            return x + y;
        }
    }
}

//controller

namespace Mainform
{
    public class LDFS
    {
        // 记录要导入的程序集
        static Assembly MyAssembly;
        /// <summary>
        /// 添加LoadDll方法
        /// </summary>
        /// <param name="lpFileName"></param>
        /// <returns></returns>
        private byte[] LoadDll(string lpFileName)
        {
            Assembly NowAssembly = Assembly.GetEntryAssembly();
            Stream fs = null;
            try
            {// 尝试读取资源中的 DLL 同一命名空间下
                fs = NowAssembly.GetManifestResourceStream(NowAssembly.GetName().Name + "." + lpFileName);
            }
            finally
            {// 如果资源没有所需的 DLL ,就查看硬盘上有没有,有的话就读取
                if (fs == null && !File.Exists(lpFileName))
                    throw (new Exception(" 找不到文件 :" + lpFileName));
                else if (fs == null && File.Exists(lpFileName))
                {
                    FileStream Fs = new FileStream(lpFileName, FileMode.Open);
                    fs = (Stream)Fs;
                }
            }
            byte[] buffer = new byte[(int)fs.Length];
            fs.Read(buffer, 0, buffer.Length);
            fs.Close();
            return buffer; // 以 byte[] 返回读到的 DLL
        }
        /// <summary>
        /// 添加UnLoadDll方法来卸载DLL
        /// </summary>
        public void UnLoadDll()
        {// 使 MyAssembly 指空
            MyAssembly = null;
        }

        /// <summary>
        /// 添加Invoke方法来进行对DLL中方法的调用
        /// </summary>
        /// <param name="lpFileName">dll名称</param>
        /// <param name="Namespace">命名空间</param>
        /// <param name="ClassName">类名</param>
        /// <param name="lpProcName">调用函数的名称</param>
        /// <param name="ObjArray_Parameter">参数</param>
        /// <returns></returns>
        public object Invoke(string lpFileName, string Namespace, string ClassName, string lpProcName, object[] ObjArray_Parameter)
        {
            try
            {// 判断 MyAssembly 是否为空或 MyAssembly 的命名空间不等于要调用方法的命名空间,如果条件为真,就用 Assembly.Load 加载所需 DLL 作为程序集
                if (MyAssembly == null || MyAssembly.GetName().Name != Namespace)
                    MyAssembly = Assembly.Load(LoadDll(lpFileName));
                Type[] type = MyAssembly.GetTypes();
                foreach (Type t in type)
                {
                    if (t.Namespace == Namespace && t.Name == ClassName)
                    {
                        MethodInfo m = t.GetMethod(lpProcName);
                        if (m != null)
                        {// 调用并返回
                            object o = Activator.CreateInstance(t);
                            return m.Invoke(o, ObjArray_Parameter);
                        }
                        else
                            System.Windows.Forms.MessageBox.Show(" 装载出错 !");
                    }

                }

            }
            catch (System.NullReferenceException e)
            {
                System.Windows.Forms.MessageBox.Show(e.Message);
            }
            return (object)0;
        }

        public object Invoke(string lpFileName, string Namespace, string ClassName)
        {
            try
            {// 判断 MyAssembly 是否为空或 MyAssembly 的命名空间不等于要调用方法的命名空间,如果条件为真,就用 Assembly.Load 加载所需 DLL 作为程序集
                if (MyAssembly == null || MyAssembly.GetName().Name != Namespace)
                    MyAssembly = Assembly.Load(LoadDll(lpFileName));
                Type type = MyAssembly.GetType(Namespace + "." + ClassName);
                if (type.Namespace == Namespace && type.Name == ClassName)
                {
                    object classobj = Activator.CreateInstance(type);
                    return classobj;
                }
                else
                    System.Windows.Forms.MessageBox.Show(" 命名空间或类名错误 !");

            }
            catch (System.NullReferenceException e)
            {
                System.Windows.Forms.MessageBox.Show(e.Message);
            }
            return (object)0;
        }
    }
}

//调用

public partial class Mainform : Form
    {
        public Mainform()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            LDFS myldfs = new LDFS();
            object myobj = myldfs.Invoke("Dynamic_linking.dll", "Dynamic_linking", "ShowErrorForm");
            ((Form)myobj).Show();
            #region --加载dll--
            //利用反射进行动态加载和调用.
            //Assembly ass = Assembly.LoadFrom(Environment.CurrentDirectory + "//Dynamic_linking.dll"); //利用dll的路径加载,同时将此程序集所依赖的程序集加载进来,需后辍名.dll
            Assembly.LoadFile 只加载指定文件,并不会自动加载依赖程序集.Assmbly.Load无需后辍名

            加载dll后,需要使用dll中某类.
            //Type type = ass.GetType("Dynamic_linking.ShowErrorForm");//利用类型的命名空间和名称获得类型

            需要实例化类型,才可以使用,参数可以人为的指定,也可以无参数,静态实例可以省略
            //Object obj = Activator.CreateInstance(type, null);//利用指定的参数实例话类型
            //((Form)obj).Show();
            //调用类型中的某个方法:
            //需要首先得到此方法
            //MethodInfo mi = type.GetMethod("Add");//通过方法名称获得方法

            //然后对方法进行调用,多态性利用参数进行控制
            //object myobj = mi.Invoke(obj, new object[]{2,3});//根据参数直线方法,返回值就是原方法的返回值
            #endregion
        }

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值