Frage

Wir haben eine verwaltete App, das verwendet eine Baugruppe. Das Assembly verwendet einige nicht verwaltete C ++ Code.

Die Managed C ++ Code ist in einer DLL, die auf mehreren anderen DLLs abhängt. Alle diese Dlls werden durch diesen Code geladen. (Wir laden alle dll ist das ImageCore.dll auf den ersten abhängt, so können wir sagen, welche fehlen, sonst wäre es zeigen sich nur als ImageCore.dll zu Last fehlgeschlagen ist, und die Protokolldatei keine Hinweise darauf, warum geben würde).

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");
        }
    }
}

Und dieser Code wird aufgerufen, indem

public class ImageDoc : IDisposable {
    static ImageDoc()
    {
        ImageHawk.ImageCore.Utility.Interop.PreloadAssemblies();
    }
    ...
}

Welche ist statischer Konstruktor.

So nahe, wie ich es verstehen kann, sobald wir ein ImageDoc Objekt zu verwenden versuchen, die DLL, die das enthält Assembly geladen wird und als Teil dieser Last, der statische Konstruktor wird aufgerufen, was wiederum bewirkt, dass mehrere andere DLLs geladen als gut. Was ich versuche, herauszufinden, ist, wie wir DeFer Laden dieses DLLs, so dass wir nicht Smack Dab in diese Lader Sperre ausführen, die aufgrund des statischen Konstruktor hinausgeworfen wird.

Ich habe so viel zusammen genäht, indem man:

  1. http: / /social.msdn.microsoft.com/Forums/en-US/vsto/thread/dd192d7e-ce92-49ce-beef-3816c88e5a86
  2. http://msdn.microsoft.com /en-us/library/aa290048%28VS.71%29.aspx
  3. http://forums.devx.com/showthread.php?t=53529
  4. http://www.yoda.arachsys.com/csharp/beforefieldinit.html

Aber ich kann einfach nicht scheinen, einen Weg zu finden, um diese externen DLLs Last zu erhalten, ohne es an dem Punkt, geschieht das Laden von Klassen ist. Ich glaube, ich brauche diese Loadlibrary bekommen Anrufe aus dem statischen Konstruktor, aber nicht wissen, wie sie genannt zu bekommen, bevor sie benötigt werden (außer, wie es hier geschehen). Ich würde es vorziehen, nicht diese Art von Wissen über die DLLs in jede Anwendung, die diese setzen müssen Assembly verwendet. (Und ich bin mir nicht sicher, dass selbst das Problem beheben würde ....

Das Merkwürdige ist, dass die Ausnahme wird nur der Fall zu sein, während im Debugger ausgeführt wird, nicht während außerhalb des Debugger ausgeführt wird.

Wie schaffe ich es, diese DLLs zu laden, ohne Lauf in Konflikt geraten:

LoadLibrary <- .NET loads the class from assembly dll 
DllMain 
LoadLibrary <- -Due to Static ctor 
DllMain
War es hilfreich?

Lösung

LoaderLock ist ein MDA (Managed Debugging Assistant) Warnung aus dem Debugger. Es sagt Ihnen, dass es könnte ein Problem mit dem Code. Es geschieht nur, wenn unter dem Debugger ausgeführt wird, weil es der Debugger ist, dass die MDA prüft macht Ihnen mitteilen zu können, dass unter bestimmten Umständen ein Deadlock „ können auftreten“.

Leider kann ich Ihnen nicht viel helfen, weiter als das. Meine Erfahrung von LoaderLock ist, dass (a) es ist eine geheimnisvolle Warnung, dass VS gibt Ihnen, aber es gibt sehr wenig Unterstützung sagen Ihnen, was wirklich zu tun, um es zu lösen, und (b) unsere Anwendung für 4 Jahre wurde mit einem LoaderLock läuft abgehend (in DirectX, es ist so nicht einmal in unserem Code) und es ist nie tatsächlich verursacht ein Problem, andere als ein lästiger Aufwand ist jedes Mal, wenn wir unter dem Debugger ausführen. YMMV natürlich.

(Sie können den MDA in Debug deaktivieren -> Ausnahmen im Managed Debugging Assistants Abschnitt, aber jedes Mal, wenn Sie diese Einstellungen zurücksetzen, die verdammt MDA schaltet sich wieder ein)

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top