어셈블리를 사용하는 관리되는 앱이 있습니다. 이 어셈블리는 관리되지 않는 C++ 코드를 사용합니다.로더 잠금을 피하려면 어떻게해야합니까?
Managed C++ 코드는 다른 여러 dll에 의존하는 dll에 있습니다. 이러한 DLL은 모두이 코드에 의해로드됩니다. (우리는 ImageCore.dll이 처음에 의존하는 모든 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이 발생합니다. 또한로드 될 수 있습니다. 내가 알아 내려고하는 것은 정적 생성자로 인해 쫓겨나고있는이 로더 잠금에 smack dab를 실행하지 않도록 DLL의 로딩을 연기하는 방법입니다.
- 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
은 귀하의 질문에 정확히 무엇 (당신은 디버그에서 MDA를 비활성화 할 수 있습니다> 관리 디버깅 도우미 섹션하지만 이러한 설정을 재설정 할 때마다에서 예외가, 망할 MDA 다시 켜집니다)? – Gabe
로드하지 못하도록 해당 DLL을로드하는 방법 : LoadLibrary <- .NET이 어셈블리 DLL에서 클래스를로드합니다. DllMain LoadLibrary <- 정적 ctor로 인해 DllMain – boatcoder