日韩黑丝制服一区视频播放|日韩欧美人妻丝袜视频在线观看|九九影院一级蜜桃|亚洲中文在线导航|青草草视频在线观看|婷婷五月色伊人网站|日本一区二区在线|国产AV一二三四区毛片|正在播放久草视频|亚洲色图精品一区

分享

C#中動(dòng)態(tài)加載和卸載DLL

 命運(yùn)之輪 2009-01-19

在C++中加載和卸載DLL是一件很容易的事,LoadLibrary和FreeLibrary讓你能夠輕易的在程序中加載DLL,然后在任何地方卸載。在C#中我們也能使用Assembly.LoadFile實(shí)現(xiàn)動(dòng)態(tài)加載DLL,但是當(dāng)你試圖卸載時(shí),你會(huì)很驚訝的發(fā)現(xiàn)Assembly沒有提供任何卸載的方法。這是由于托管代碼的自動(dòng)垃圾回收機(jī)制會(huì)做這件事情,所以C#不提供釋放資源的函數(shù),一切由垃圾回收來做。 

這引發(fā)了一個(gè)問題,用Assembly加載的DLL可能只在程序結(jié)束的時(shí)候才會(huì)被釋放,這也意味著在程序運(yùn)行期間無法更新被加載的DLL。而這個(gè)功能在某些程序設(shè)計(jì)時(shí)是非常必要的,考慮你正在用反射機(jī)制寫一個(gè)查看DLL中所有函數(shù)詳細(xì)信息的程序,程序提供一個(gè)菜單讓用戶可以選擇DLL文件,這時(shí)就需要讓程序能夠卸載DLL,否則一旦用戶重新得到新版本DLL時(shí),必須要重新啟動(dòng)程序,重新選擇加載DLL文件,這樣的設(shè)計(jì)是用戶無法忍受的。

C#也提供了實(shí)現(xiàn)動(dòng)態(tài)卸載DLL的方法,通過AppDomain來實(shí)現(xiàn)。AppDomain是一個(gè)獨(dú)立執(zhí)行應(yīng)用程序的環(huán)境,當(dāng)AppDomain被卸載的時(shí)候,在該環(huán)境中的所有資源也將被回收。關(guān)于AppDomain的詳細(xì)資料參考MSDN。下面是使用AppDomain實(shí)現(xiàn)動(dòng)態(tài)卸載DLL的代碼,

using System;
using System.Collections.Generic;
using System.Text;
using System.Threading;
using System.Reflection;
namespace UnloadDll
{
    class Program
    {
        static void Main(string[] args)
        {
            string callingDomainName = AppDomain.CurrentDomain.FriendlyName;//Thread.GetDomain().FriendlyName;
            Console.WriteLine(callingDomainName);
            AppDomain ad = AppDomain.CreateDomain("DLL Unload test");
            ProxyObject obj = (ProxyObject)ad.CreateInstanceFromAndUnwrap(@"UnloadDll.exe", "UnloadDll.ProxyObject");
            obj.LoadAssembly();
            obj.Invoke("TestDll.Class1", "Test", "It's a test");
            AppDomain.Unload(ad);
            obj = null;
            Console.ReadLine();
        }
    }
    class ProxyObject : MarshalByRefObject
    {
        Assembly assembly = null;
        public void LoadAssembly()
        {
            assembly = Assembly.LoadFile(@"TestDLL.dll");           
        }
        public bool Invoke(string fullClassName, string methodName, params Object[] args)
        {
            if(assembly == null)
                return false;
            Type tp = assembly.GetType(fullClassName);
            if (tp == null)
                return false;
            MethodInfo method = tp.GetMethod(methodName);
            if (method == null)
                return false;
            Object obj = Activator.CreateInstance(tp);
            method.Invoke(obj, args);
            return true;           
        }
    }
}

注意:

1. 要想讓一個(gè)對象能夠穿過AppDomain邊界,必須要繼承MarshalByRefObject類,否則無法被其他AppDomain使用。

2. 每個(gè)線程都有一個(gè)默認(rèn)的AppDomain,可以通過Thread.GetDomain()來得到

    本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點(diǎn)擊一鍵舉報(bào)。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評(píng)論

    發(fā)表

    請遵守用戶 評(píng)論公約

    類似文章 更多