2009-04-07 11 views

回答

2

強制DLL出在.net的過程中的唯一方法是卸載,其中DLL被加載在AppDomain。除非你創建一個單獨的AppDomain來運行DllImport代碼,否則這是不可能的。

另外我知道這個政策適用於託管的DLL。我不是100%確定這是否適用於通過PINvoke加載的DLL,但我相當肯定。

+0

對我來說,它並沒有與pinvoke添加DLL工作。可能依賴於dll。 – Sire 2012-09-10 08:37:42

2

只有當你創建一個新的AppDomain和DLL加載到域。之後,您可以卸載AppDomain並卸載dll。

0

卸載應用程序域並不是唯一的答案。您也可以通過pinvoke使用 LoadLibrary FreeLibrary 來卸載庫。只要確保你打電話 FreeLibrary 兩次,以確保你的庫的任何依賴關係也被卸載。

我沒有測試過這一點,但我想這樣一類將使這樣做更容易:

                        
                          [DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)] 
private static extern IntPtr LoadLibrary(string libname); 

[DllImport("kernel32.dll", CharSet = CharSet.Auto)] 
private static extern bool FreeLibrary(IntPtr hModule); 

class LibraryHandle 
{ 
    readonly string libName; 
    int refCount = 0; 
    IntPtr handle; 

    public LibraryHandle(string name) 
    { 
     libName = name; 
    } 

    public void Increment() 
    { 
     if (refCount == 0) 
     { 
      handle = LoadLibrary(libName); 
      if (Handle == IntPtr.Zero) 
      { 
       int error = Marshal.GetLastWin32Error(); 
       throw new Exception(string.Format("{0})", error)); 
      } 
     } 
     ++refCount; 
    } 

    public void Decrement() 
    { 
     if (refCount <= 0) 
      return; 

     if (--refCount) 
     { 
      // It might be better in some cases to: 
      // while(FreeLibrary(handle)); 
      FreeLibrary(handle); 
      FreeLibrary(handle); 
     } 
    } 
} 

                        
                      

一定要小心,這個例子 不是線程安全 ,你會想保證在ASP.NET中,並且不會執行完整的錯誤檢查。

而且,因爲這可能會違反運行時做一些假設,你沒有加載可能不是一個好主意庫使用 FreeLibrary

另一種方法是在新 AppDomain 執行任何操作,然後卸載它,當你完成。