2010-03-19 2 views
2

У нас есть управляемое приложение, в котором используется сборка. Эта сборка использует некоторый неуправляемый код на 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 в эту блокировку загрузчика, которая вызывается из-за статического конструктора.

Я кусочкам столько вместе, глядя на:

  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

Но я просто не могу найти способ заставить эти внешние DLL загружаться, если это не происходит в точке класс загружается. Я думаю, мне нужно получить эти вызовы LoadLibrary из статического конструктора, но не знаю, как их вызвать, прежде чем они понадобятся (за исключением того, как это делается здесь). Я бы предпочел не добавлять эти знания DLL в каждое приложение, использующее эту сборку. (И я не уверен, что даже исправить проблему ....

Самое странное в том, что исключение только кажется, что происходит во время работы в отладчик, а не во время работы вне отладчика.

Как мне удается загрузить эти библиотеки DLL, не вступая в противоречие:.

LoadLibrary <- .NET loads the class from assembly dll 
DllMain 
LoadLibrary <- -Due to Static ctor 
DllMain 
+0

Что на ваш вопрос именно? – Gabe

+0

Как загрузить эти DLL-файлы без использования: LoadLibrary <- .NET загружает класс из сборной DLL DllMain LoadLibrary <- из-за Static ctor DllMain – boatcoder

ответ

3

LoaderLock является MDA (Управляемая Debugging Assistant) предупреждение из отладчика Он говорит вам, что может быть проблема с кодом Это происходит только при запуске u отладчика, потому что это отладчик, который делает проверки MDA, чтобы сообщить вам, что при некоторых обстоятельствах возникает тупик «может».

К сожалению, я не могу вам помочь намного дальше. Мой опыт LoaderLock заключается в том, что (а) это загадочное предупреждение, которое дает вам VS, но есть небольшая поддержка, говорящая вам, что на самом деле делать для его решения, и (б) наше приложение работает в течение 4 лет с помощью LoaderLock (в DirectX, так что это даже не в нашем коде), и это никогда не вызывало проблемы, кроме как раздражающих хлопот каждый раз, когда мы запускаем под отладчиком. Разумеется, YMMV.

(Вы можете отключить MDA в Debug -> Исключения в разделе Помощники Управляемые отладки, но каждый раз, когда вы сбрасываете эти настройки, проклятая MDA поворачивается на)

Смежные вопросы