У нас есть управляемое приложение, в котором используется сборка. Эта сборка использует некоторый неуправляемый код на C++.Как избежать блокировки загрузчика?
Управляемый код C++ находится в dll, который зависит от нескольких других DLL. Все эти Dll загружаются этим кодом. (Мы загружаем все DLL, с которых зависит файл ImageCore.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
Как загрузить эти DLL-файлы без использования: LoadLibrary <- .NET загружает класс из сборной DLL DllMain LoadLibrary <- из-за Static ctor DllMain – boatcoder