2011-03-21 162 views
0

我在我的C#ASP.Net Web應用程序中使用DLLImport加載C++ DLL。該DLL基本上讀取一些CSV文件,並操縱它們並創建新文件。如何在C#中卸載C++ DLL

成功運行該方法並再次運行後,我得到了C++異常。

我想從網站卸載C++ DLL,以便用戶可以重新加載DLL並重新運行該方法。你知道如何消除這個錯誤,或者擺脫這個錯誤信息,以便DLL在運行後可以被卸載嗎?

+0

什麼是錯誤信息? – 2011-03-21 22:31:36

+0

它表示[SEHException(0x80004005):外部組件已引發異常。]異常詳細信息:System.Runtime.InteropServices.SEHException:外部組件已引發異常。 – InfoLearner 2011-03-21 22:38:40

+0

把C++代碼放在這裏。也許有一些內存泄漏或邏輯問題!您不需要從內存中卸載任何'DLL',因爲'DLL'文件可以在同一時間從多個應用程序訪問。 – Jalal 2011-03-21 22:39:22

回答

2

據我所知,沒有辦法做後期綁定與C#。

但是,您可以通過創建一個C++ DLL並使用它來完成。假設您對C++有足夠的瞭解,那麼您只需要DLL導出的單個函數,該函數使用LoadLibrary加載CSV操作DLL,GetProcAddress以檢索要調用的函數的地址,然後使用FreeLibrary來釋放圖書館。

一個例子是這樣的:

extern "C" { 
    __declspec(dllexport) bool InvokeMyFunction() { 
    HMODULE lib = LoadLibrary("csvlib.dll"); 
    if (!lib) 
     return false; 

    void (*func)(int) = (void (*)(int))GetProcAddress(lib, "MyCsvFunc"); 
    if (!func) 
     return false; 

    func(5); 

    FreeLibrary(lib); 

    return true; 
    } 
} 

這不是完全安全的,雖然。如果可能的話,最好找出你的DLL函數被多次調用的問題,並修復它。

+0

如果C++在其進程中鎖定文件,並且如果我調用FreeLibrary方法,是否還會釋放鎖定的文件以及釋放C++ DLL? – InfoLearner 2011-03-21 22:53:34

+0

不一定。只有在DLL中的卸載代碼明確關閉文件句柄。 – CodesInChaos 2011-03-21 22:58:49

+0

我最初的猜測是它不會釋放任何資源;有可能DLL可能已經將句柄傳遞迴加載器。不過,我並不完全確定。有人可能會更清楚。 – 2011-03-21 23:00:29

0

根據我的信息,非託管DLL總是加載到主應用程序域中。如果不是這樣,你可以用這種方式卸載DLL。

由於這是最好的問題,我想提出一個不同的解決方案:爲什麼不寫一個單獨的命令行程序來完成工作並根據需要運行它。它將運行在它自己的過程中,並在運行後完全卸載。

+0

所以你建議我應該在.bat文件中調用C++ Dll的方法?或者我應該將DLL轉換爲.exe,然後調用該方法? – InfoLearner 2011-03-21 23:25:16

+0

我的意思是你會在你的解決方案中寫一個小命令行C#程序,它只不過是調用非託管函數。這不是最佳的,但是會是一個非常便宜的快速修復程序。 您需要讓ASP.NET進程訪問此exe文件並將其與Web應用程序一起部署。 – steinar 2011-03-21 23:30:47

+0

不錯的主意。如何將輸入參數傳遞給函數? – InfoLearner 2011-03-22 00:52:42

1

如果它是你的代碼...爲什麼不只是提供一個FreeResources函數?

作爲一種替代方案,修復您的代碼以使您的函數可重入也可以工作。