zoukankan      html  css  js  c++  java
  • C#中动态加载和卸载DLL

      在C++中加载和卸载DLL是一件很容易的事,LoadLibrary和FreeLibrary让你能够轻易的在程序中加载DLL,然后在任何地方 卸载。在C#中我们也能使用Assembly.LoadFile实现动态加载DLL,但是当你试图卸载时,你会很惊讶的发现Assembly没有提供任何 卸载的方法。这是由于托管代码的自动垃圾回收机制会做这件事情,所以C#不提供释放资源的函数,一切由垃圾回收来做。 
      这引发了一个问题,用Assembly加载的DLL可能只在程序结束的时候才会被释放,这也意味着在程序运行期间无法更新被加载的DLL。而这个功能在某 些程序设计时是非常必要的,考虑你正在用反射机制写一个查看DLL中所有函数详细信息的程序,程序提供一个菜单让用户可以选择DLL文件,这时就需要让程 序能够卸载DLL,否则一旦用户重新得到新版本DLL时,必须要重新启动程序,重新选择加载DLL文件,这样的设计是用户无法忍受的。 
      C#也提供了实现动态卸载DLL的方法,通过AppDomain来实现。AppDomain是一个独立执行应用程序的环境,当AppDomain被卸载的 时候,在该环境中的所有资源也将被回收。关于AppDomain的详细资料参考MSDN。下面是使用AppDomain实现动态卸载DLL的代码:

     1 using System; 
     2 using System.Collections.Generic; 
     3 using System.Text; 
     4 using System.Threading; 
     5 using System.Reflection; 
     6 namespace UnloadDll 
     7 { 
     8 class Program 
     9 { 
    10 static void Main(string[] args) 
    11 { 
    12 string callingDomainName = AppDomain.CurrentDomain.FriendlyName;//Thread.GetDomain().FriendlyName; 
    13 Console.WriteLine(callingDomainName); 
    14 AppDomain ad = AppDomain.CreateDomain("DLL Unload test"); 
    15 ProxyObject obj = (ProxyObject)ad.CreateInstanceFromAndUnwrap(@"UnloadDll.exe", "UnloadDll.ProxyObject"); 
    16 obj.LoadAssembly(); 
    17 obj.Invoke("TestDll.Class1", "Test", "It's a test"); 
    18 AppDomain.Unload(ad); 
    19 obj = null; 
    20 Console.ReadLine(); 
    21 } 
    22 } 
    23 class ProxyObject : MarshalByRefObject 
    24 { 
    25 Assembly assembly = null; 
    26 public void LoadAssembly() 
    27 { 
    28 assembly = Assembly.LoadFile(@"TestDLL.dll"); 
    29 } 
    30 public bool Invoke(string fullClassName, string methodName, params Object[] args) 
    31 { 
    32 if(assembly == null) 
    33 return false; 
    34 Type tp = assembly.GetType(fullClassName); 
    35 if (tp == null) 
    36 return false; 
    37 MethodInfo method = tp.GetMethod(methodName); 
    38 if (method == null) 
    39 return false; 
    40 Object obj = Activator.CreateInstance(tp); 
    41 method.Invoke(obj, args); 
    42 return true; 
    43 } 
    44 } 
    45 } 

    注意: 

    1. 要想让一个对象能够穿过AppDomain边界,必须要继承MarshalByRefObject类,否则无法被其他AppDomain使用。 

    2. 每个线程都有一个默认的AppDomain,可以通过Thread.GetDomain()来得到。

    详细参考:http://www.cnblogs.com/foman/archive/2009/10/18/1585655.html

  • 相关阅读:
    把影响集中到一个点
    How to avoid Over-fitting using Regularization?
    适定性问题
    Numerical Differentiation 数值微分
    What Every Computer Scientist Should Know About Floating-Point Arithmetic
    Generally a good method to avoid this is to randomly shuffle the data prior to each epoch of training.
    What is the difference between iterations and epochs in Convolution neural networks?
    Every norm is a convex function
    Moore-Penrose Matrix Inverse 摩尔-彭若斯广义逆 埃尔米特矩阵 Hermitian matrix
    perl 类里的函数调用其他类的函数
  • 原文地址:https://www.cnblogs.com/wmcoder/p/5171183.html
Copyright © 2011-2022 走看看