Pregunta

Tenemos una aplicación administrada, que utiliza un conjunto. Que el montaje utiliza algún código no administrado C ++.

El código de C ++ es en un DLL, que depende de varios otros DLL. Todos estos archivos DLL se cargan por este código. (Cargamos todos los DLL que ImageCore.dll depende en primer lugar, por lo que podemos decir cuáles faltan, de lo contrario sería simplemente aparecer como ImageCore.dll no se pudo cargar, y el archivo de registro no daría pistas sobre por qué).

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

Y el código es llamado por

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

Lo que es constructor estático.

Lo más cerca que puedo entender que, tan pronto como se intenta utilizar un objeto ImageDoc, la DLL que contiene ese conjunto está cargado y como parte de esa carga, el constructor estático se llama que a su vez provoca varios otros archivos DLL a ser cargado también. Lo que estoy tratando de averiguar, es ¿cómo nos remitimos carga de los archivos DLL de manera que no corremos tortazo en esta cerradura cargador que está siendo expulsado por el constructor estático.

He monté esto mucho juntos mirando a:

  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

Pero me parece que no puede encontrar una manera de obtener estos archivos DLL externa para cargar sin que esto ocurra en el punto de la clase se está cargando. Creo que necesito para conseguir estas llamadas LoadLibrary fuera del constructor estático, pero no saben cómo conseguir que llaman antes de que se necesitan (a excepción de cómo se hace aquí). Yo preferiría no tener que soportar este tipo de conocimiento de los archivos DLL en cada aplicación que utiliza este montaje. (Y no estoy seguro de que incluso puede solucionar el problema ....

Lo más curioso es que la única excepción parece estar ocurriendo mientras se ejecuta en el depurador, no mientras se ejecuta fuera del depurador.

¿Cómo me las arreglo para cargar los archivos DLL sin violar:

LoadLibrary <- .NET loads the class from assembly dll 
DllMain 
LoadLibrary <- -Due to Static ctor 
DllMain
¿Fue útil?

Solución

LoaderLock es un MDA (Managed Depuración Asistente) Advertencia desde el depurador. Se da a conocer que hay podría haber un problema con el código. Esto sólo ocurre cuando se ejecuta en el depurador porque es el depurador que está haciendo la MDA comprueba para informarle de que en algunas circunstancias un callejón sin salida " puede producirse".

Por desgracia, no puedo ayudarle mucho más lejos que eso. Mi experiencia de LoaderLock es que (a) es una misteriosa advertencia de que VS le da, pero hay poco apoyo valioso que le dice qué hacer realmente para resolverlo, y (b) nuestra aplicación ha estado funcionando durante 4 años con un LoaderLock ir fuera (en DirectX, por lo que ni siquiera está en nuestro código) y nunca ha causado realmente un problema, aparte de ser una molestia molesto cada vez que nos encontramos en el depurador. Tu caso es distinto, por supuesto.

(Puede desactivar la MDA en Depurar -> Excepciones en la sección Asistentes Depuración Gestionado, pero cada vez que se restablecieron los ajustes, el maldito MDA se vuelve a encender)

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top