我們有一個託管應用程序,使用程序集。該程序集使用一些非託管C++代碼。如何避免裝載機鎖?
託管C++代碼是在一個DLL,這取決於其他幾個DLL。所有這些Dll都由此代碼加載。 (我們首先加載ImageCore.dll所依賴的所有dll,這樣我們就可以知道哪些是丟失的,否則它只會顯示爲ImageCore.dll加載失敗,並且日誌文件不會提供關於原因的線索)。
class Interop
{
private const int DONT_RESOLVE_DLL_REFERENCES = 1;
private static log4net.ILog log = log4net.LogManager.GetLogger("Imagecore.NET");
[DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
private static extern IntPtr LoadLibraryEx(string fileName, IntPtr dummy, int flags);
[DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
private static extern IntPtr FreeLibrary(IntPtr hModule);
static private String[] libs = { "log4cplus.dll", "yaz.dll", "zlib1.dll", "libxml2.dll" };
public static void PreloadAssemblies()
{
for (int i=0; i < libs.Length; ++i) {
String libname = libs[i];
IntPtr hModule = LoadLibraryEx(libname, IntPtr.Zero, DONT_RESOLVE_DLL_REFERENCES);
if(hModule == IntPtr.Zero) {
log.Error("Unable to pre-load '" + libname + "'");
throw new DllNotFoundException("Unable to pre-load '" + libname + "'");
} else {
FreeLibrary(hModule);
}
}
IntPtr h = LoadLibraryEx("ImageCore.dll", IntPtr.Zero, 0);
if (h == IntPtr.Zero) {
throw new DllNotFoundException("Unable to pre-load ImageCore.dll");
}
}
}
而這種代碼是由
public class ImageDoc : IDisposable {
static ImageDoc()
{
ImageHawk.ImageCore.Utility.Interop.PreloadAssemblies();
}
...
}
這是靜態構造函數調用。
盡我所知,只要我們嘗試使用ImageDoc對象,就會加載包含該程序集的dll,並且作爲該加載的一部分,將調用靜態構造函數,從而導致其他幾個DLL也要加載。我試圖弄清楚的是,我們如何推遲加載這些DLL,以便我們不會因爲靜態構造函數而將smack dab運行到正在被踢出的加載器鎖中。
我通過看這個拼湊在一起得多:
- http://social.msdn.microsoft.com/Forums/en-US/vsto/thread/dd192d7e-ce92-49ce-beef-3816c88e5a86
- http://msdn.microsoft.com/en-us/library/aa290048%28VS.71%29.aspx
- http://forums.devx.com/showthread.php?t=53529
- http://www.yoda.arachsys.com/csharp/beforefieldinit.html
但我似乎無法找到一個方式來獲得這些外部DLL加載沒有發生在點類正在加載。我想我需要將這些LoadLibrary調用從靜態構造函數中取出,但不知道如何在需要它們之前調用它們(除了這裏是如何完成的)。我寧願不必將這種dll的知識應用到使用此程序集的每個應用程序中。 (我不知道,甚至會解決這個問題....
奇怪的是,例外只出現在調試器中運行時,不會在調試器外部運行時發生。
如何管理加載這些DLL而不相抵觸運行:
LoadLibrary <- .NET loads the class from assembly dll
DllMain
LoadLibrary <- -Due to Static ctor
DllMain
什麼是你的問題是什麼呢? – Gabe 2010-03-19 21:16:37
我該如何設法加載這些DLL而不會碰到: LoadLibrary < - .NET從程序集DLL加載類 DllMain LoadLibrary < - 由於靜態ctor DllMain – boatcoder 2010-03-19 21:19:57