2012-03-27 144 views
3

我有一個C#程序使用DL​​LImport(stdcall)調用C++ DLL。C#DLLImport導致太多的IO操作

但是使用進程監視器我發現每次我在C++ dll中調用一個函數時,它都會導致三個IO操作來打開DLL文件,讀取並關閉它。

IO operations 我打電話的C++ dll函數是靜態的。我沒有C++ dll的來源來改變它。我能做些什麼來避免這些過度的IO操作?我可以使用DLLImport從內存而不是文件加載DLL嗎?有什麼建議麼?

+0

調用普通的'託管'dll時的行爲是什麼?有什麼區別或這是標準的方式? – Steve 2012-03-27 23:04:13

+0

這種行爲是由CLR還是由DLL本身造成的?嘗試在DLL中調用一個空函數,看看問題是否存在。 – usr 2012-03-27 23:09:09

+0

調用一個正常的託管dll也會導致這些IO操作,但僅限於第一次調用。對dll的下一個調用將使用與第一個調用中打開的dll相同的「指針」,所以dll不會再次打開。 – walteram 2012-03-27 23:12:10

回答

1

嘗試顯式加載DLL,然後進行調用。在關閉應用程序之前,將指針保留在DLL中並卸載它。

[DllImport("kernel32.dll")] 
public static extern IntPtr LoadLibrary(string dllToLoad); 

[DllImport("kernel32.dll")] 
public static extern bool FreeLibrary(IntPtr hModule); 


IntPtr pDll = LoadLibrary("library.dll"); 

FreeLibrary(pDll); 
+0

這個答案是基於這個信念,即在問題中的診斷是正確的。不是這樣。 – 2012-04-18 06:27:41

+0

@DavidHeffernan同意在有問題的場景中出現問題。在每次調用後DLL都不會被卸載(如果這是真正發生的事情)。顯式加載它會增加DLL引用計數器,從而減少DLL被卸載的可能性。 – 2012-04-18 07:27:37

2

在您的問題中提出的分析是不正確的。如果這是正確的,那麼DllImport將是無用的。

不,當您調用一個用p/invoke導入的函數時,加載的DLL會保持加載狀態。每次調用導入的函數時,p/invoke系統都不會加載和卸載DLL。