Nous avons une application gérée, qui utilise un assemblage. Cet assembly utilise du code C++ non géré.Comment éviter le verrouillage de la chargeuse?
Le code C++ géré est dans une DLL, qui dépend de plusieurs autres DLL. Toutes ces DLL sont chargées par ce code. (Nous chargeons toutes les DLL dont dépend ImageCore.dll en premier, donc nous pouvons dire lesquelles sont manquantes, sinon il apparaîtrait juste comme ImageCore.dll n'a pas pu charger, et le fichier journal ne donnerait aucune indication quant à pourquoi).
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");
}
}
}
Et ce code est appelé par
public class ImageDoc : IDisposable {
static ImageDoc()
{
ImageHawk.ImageCore.Utility.Interop.PreloadAssemblies();
}
...
}
Ce qui est constructeur statique. Autant que je puisse le comprendre, dès que nous essayons d'utiliser un objet ImageDoc, la DLL qui contient cet assembly est chargée et dans le cadre de cette charge, le constructeur statique est appelé, ce qui à son tour provoque plusieurs autres DLL à charger aussi. Ce que j'essaie de comprendre, c'est comment différer le chargement de ces DLL afin de ne pas exécuter smack dab dans ce verrou de chargeur qui est expulsé à cause du constructeur statique.
J'ai rapiécé ce bien ensemble en regardant:
- 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
Mais je ne peux pas sembler trouver un façon d'obtenir ces DLL externes à charger sans qu'il se passe au point le la classe est en cours de chargement. Je pense que j'ai besoin de sortir ces appels de LoadLibrary du constructeur statique, mais je ne sais pas comment les appeler avant qu'ils soient nécessaires (excepté comment c'est fait ici). Je préférerais ne pas avoir à mettre ce genre de connaissance des dlls dans chaque application qui utilise cette assemblée. (Et je ne suis pas sûr que cela même résoudre le problème ....
La chose étrange est que l'exception ne semble se produire lors de l'exécution dans le débogueur, pas en cours d'exécution en dehors du débogueur.
Comment puis-je parviens à charger les DLL sans aller à l'encontre de:.
LoadLibrary <- .NET loads the class from assembly dll
DllMain
LoadLibrary <- -Due to Static ctor
DllMain
Quelle est votre question exactement? – Gabe
Comment puis-je gérer pour charger ces DLL sans rencontrer les problèmes suivants: LoadLibrary <- .NET charge la classe à partir de la DLL d'assemblage DllMain LoadLibrary <- Due à Static ctor DllMain – boatcoder