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

    技术2022-05-17  62

    //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        }

     


    最新回复(0)