2011-01-21 10 views
5

Estoy tratando de retrasar la carga de mis .dlls dependientes para una aplicación C++/CLI para que pueda probar su existencia y advertir al usuario en lugar de simplemente fallar.¿Cómo puedo retrasar la carga de .dlls en una aplicación C++ - CLI (.net)?

He intentado añadir los archivos DLL de MyProject-> Propiedades-> ConfigurationProperties-> Linker-> input-> DLLS retardo cargados ... pero eso me da una advertencia de que no se hace referencia a ellos:

5> LINK: advertencia LNK4199: /DELAYLOAD:Util.dll ignorado; no hay importaciones que se encuentran desde Util.dll

Si elimino un archivo .dll y ejecutar la aplicación se bloquea y desea enviar información a Microsoft sobre el .dll que faltan por lo que parece que todavía está tratando de cargar todos los módulos en inicio y tener un ataque como resultado.

FYI, mi aplicación de inicio se ve algo como esto:

using namespace System; 
using namespace System::Collections::ObjectModel; 
using namespace Microsoft::Win32; 

[STAThreadAttribute] 
int main(array<System::String ^> ^args) 
{ 
    try 
    { 
     // Enabling Windows XP visual effects before any controls are created 
     Application::EnableVisualStyles(); 
     Application::SetCompatibleTextRenderingDefault(false); 

     // First make sure we have all the .dlls we need 
     ArrayList^ missingDlls = gcnew ArrayList(); 
     Assembly^ assembly = Assembly::GetEntryAssembly(); 
     array<System::Reflection::AssemblyName^>^ referencedAssemblies = assembly->GetReferencedAssemblies(); 
     for each(System::Reflection::AssemblyName^ referencedAssemblyName in referencedAssemblies) 
     { 
      try 
      { 
       Assembly^ a = assembly->Load(referencedAssemblyName); 
       if(a == nullptr) 
       { 
        missingDlls->Add(referencedAssemblyName->Name); 
       } 
      } 
      catch(System::Exception^ e) 
      { 
       MessageBox::Show("Error loading "+referencedAssemblyName->Name); 
      } 
     } 

     ... 

Respuesta

7

opción/delayload del enlazador sólo funciona para archivos DLL que contienen funciones compilados a código máquina nativo. El vinculador ya te dijo que no tienes ninguno.

El escenario probable aquí es que su DLL realmente contiene IL, no código de máquina. Lo cual sucederá cuando compile el código fuente con/clr en efecto y no haya usado #pragma para desactivar la generación de IL. El código de IL necesita ser convertido a código de máquina por el jitter.

Su archivo DLL se cargará dinámicamente, al igual que/delayload, tan pronto como el jitter necesite información de tipo de los metadatos del ensamblado para generar código de máquina. Para evitar la dependencia de la DLL, tendría que crear su código cuidadosamente para que el jitter nunca necesite cargar tipos de su ensamblado. Que es un problema diferente al evitar ejecutando una función cargada de retraso. El rastro de pila de InnerException de la excepción debería darle una pista clara de cómo sucedió.

+0

¿Qué significa "IL"? Sospechaba que esto probablemente iba a requerir más esfuerzo de lo que valía, y por lo que has dicho, probablemente sea así. –

+0

Desafortunadamente, nunca tuve la oportunidad de detectar la excepción y desplegarla, así que todo lo que he visto son las partes externas del informe de errores que Miscrosoft quiere enviarse. –

+1

IL == Idioma intermedio, a qué código se traduce cuando compila con/clr. La trepidación lo traduce en código de máquina. Suscríbase a AppDomain.CurrentDomain.UnhandledException para registrar excepciones no controladas como esta. Puede elevarse técnicamente antes de que su método Main() comience a funcionar si ese método usa tipos de dicho ensamblaje. –

Cuestiones relacionadas