Pregunta

Tengo un problema similar, pero sutilmente diferente, al descrito. aquí (Carga de ensamblajes y sus dependencias).

Tengo una DLL de C++ para renderizado 3D que es lo que vendemos a los clientes.Para los usuarios de .NET, tendremos un contenedor CLR a su alrededor.La DLL de C++ se puede crear en versiones de 32 y 64 bits, pero creo que esto significa que necesitamos tener dos contenedores CLR ya que el CLR se vincula a una DLL específica.

Digamos que ahora nuestro cliente tiene una aplicación .NET que puede ser de 32 o 64 bits y que, al ser una aplicación .NET pura, deja que CLR la resuelva a partir de un único conjunto de ensamblajes.La pregunta es ¿cómo puede el código de la aplicación elegir dinámicamente entre nuestras combinaciones CLR/DLL de 32 y 64 bits en tiempo de ejecución?

Aún más específicamente, ¿la respuesta sugerida a la pregunta antes mencionada también es aplicable aquí (es decir,¿Crear un controlador ResolveEvent)?

¿Fue útil?

Solución

Finalmente tengo una respuesta para esto que parece funcionar.

Compile las versiones de 32 y 64 bits, administradas y no administradas, en carpetas separadas.Luego haga que la aplicación .NET elija en tiempo de ejecución desde qué directorio cargar los ensamblados.

El problema con el uso de ResolveEvent es que solo se llama si no se encuentran ensamblados, por lo que es muy fácil terminar accidentalmente con versiones de 32 bits.En su lugar, utilice un segundo objeto AppDomain donde podamos cambiar la propiedad ApplicationBase para que apunte a la carpeta correcta.Entonces terminas con un código como:

static void Main(String[] argv)
  {
     // Create a new AppDomain, but with the base directory set to either the 32-bit or 64-bit
     // sub-directories.

     AppDomainSetup objADS = new AppDomainSetup();

     System.String assemblyDir = System.IO.Path.GetDirectoryName(Application.ExecutablePath);
     switch (System.IntPtr.Size)
     {
        case (4): assemblyDir += "\\win32\\";
           break;
        case (8): assemblyDir += "\\x64\\";
           break;
     }

     objADS.ApplicationBase = assemblyDir;

     // We set the PrivateBinPath to the application directory, so that we can still
     // load the platform neutral assemblies from the app directory.
     objADS.PrivateBinPath = System.IO.Path.GetDirectoryName(Application.ExecutablePath);

     AppDomain objAD = AppDomain.CreateDomain("", null, objADS);
     if (argv.Length > 0)
        objAD.ExecuteAssembly(argv[0]);
     else
        objAD.ExecuteAssembly("MyApplication.exe");

     AppDomain.Unload(objAD);

  }

Terminas con 2 ex: tu aplicación normal y una segunda aplicación de conmutación que elige qué bits cargar.Nota: no puedo atribuirme el mérito de los detalles de esto.Uno de mis colegas se dio cuenta de eso dada mi sugerencia inicial.Si se registra en StackOverflow, le asignaré la respuesta.

Otros consejos

Pude hacer esto hace aproximadamente un año, pero ya no recuerdo todos los detalles.Básicamente, puede usar IntPtr.Size para determinar qué DLL cargar y luego realizar la LoadLibrary real a través de p/Invoke.En ese punto, tiene el módulo en la memoria y debería poder simplemente p/Invocar funciones desde su interior; el mismo nombre del módulo no debería volver a cargarse.

Sin embargo, creo que en mi aplicación hice que la DLL de C++ se registrara como un servidor COM y luego accediera a su funcionalidad a través de un contenedor .NET generado, por lo que no sé si alguna vez probé p/Invoking directamente.

Me encontré con un escenario similar hace un tiempo.Un conjunto de herramientas que estaba usando no se comportó bien en un entorno de 64 bits y no pude encontrar una manera de forzar dinámicamente que los ensamblajes se unieran como 32 bits.

Es posible forzar que sus ensamblados funcionen en modo de 32 bits, pero esto requiere parchear el encabezado CLR (hay una herramienta que hace eso en Framework) y si sus ensamblados tienen un nombre seguro, esto no funciona.

Me temo que necesitarás crear y publicar dos conjuntos de archivos binarios para plataformas de 32 y 64 bits.

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