2010-05-10 37 views
12

Tengo un proyecto que debe compilarse y ejecutarse en modo de 64 bits. Lamentablemente, debo recurrir a una DLL que solo está disponible en el modo de 32 bits, por lo que no hay forma de que pueda albergar todo en un proyecto de 1 Visual Studio. Estoy trabajando para encontrar la mejor manera de ajustar el archivo DLL de 32 bits en su propio exe/servicio y emitir llamadas remotas (aunque en la misma máquina) a ese exe/servicio desde mi aplicación de 64 bits. Mi sistema operativo es Win7 Pro de 64 bits.Formas de acceder a una DLL de 32 bits desde un exe de 64 bits

Las llamadas requeridas para este proceso de 32 bits son varias docenas por segundo, pero bajo volumen de datos. Esta es una aplicación de análisis de imágenes en tiempo real, por lo que el tiempo de respuesta es crítico a pesar del bajo volumen. Muchas primitivas simples de envío/recepción.

Idealmente, alojaría un servicio WCF para alojar esta DLL, pero en un sistema operativo de 64 bits no se puede obligar al servicio a ejecutarse como x86. Source. Eso es realmente desafortunado ya que las llamadas de función cronometradas al servicio WCF son de solo 4 ms en mi máquina.

He experimentado con named pipes is .net. Los encontré 40-50 veces más lentos que WCF (inutilizable para mí).

¿Alguna otra opción o sugerencia para la mejor manera de acercarse a mi rompecabezas?

+0

Ver [esta respuesta] (http://stackoverflow.com/a/12938217/184528) para una lista más completa de las técnicas para acceder a archivos DLL de 32 bits de aplicaciones de 64 bits . – cdiggins

Respuesta

9

Como nota correctamente, no hay forma de mezclar bitness en el mismo proceso. Necesita un proceso separado para su parte de 32 bits.

Creo que el alojamiento de un Servicio WCF es el camino correcto a seguir. Su enlace solo habla de wcfsvchost. Estoy bastante seguro de que puede crear su propio servicio de Windows y alojar el servicio WCF en 32 bits.

Ver este enlace: How to host a WCF service in a managed application. Puede alojar su servicio en cualquier aplicación administrada, incluido un servicio de Windows, y ejecutarlo en el bitness que desee.

Esta es la cantidad de código necesario para la auto-anfitrión un servicio WCF en su aplicación, asumiendo que acaba de crear un nuevo servicio llamado MyService, y la configuración apropiada se ha agregado a App.config:

class Program 
{ 
    static void Main(string[] args) 
    { 
     using(ServiceHost host = new ServiceHost(typeof(MyService), new Uri[0])) 
     { 
      host.Open(); 
      Console.ReadKey();  
     } 
    } 
} 

El programa anterior se ejecutará igual de bien, también si lo compila explícitamente como 32 o 64 bits.

+0

¿Podrías por favor elaborar un poco? Veo que puedo crear un servicio de Windows de 32 bits, ¿cómo podría crear un servicio WCF para hacer las E/S para mi servicio de Windows de 32 bits? – bufferz

+0

Gracias driis! No sabía que podía alojar servicios WCF manualmente desde una aplicación. Esta es una solución mucho mejor que una que pensé que terminaría usando. * levanta el puño en el aire * – bufferz

+0

Ah, y por si acaso se encuentra con problemas de seguridad, aquí hay un enlace: http://blogs.msdn.com/amitlale/archive/2007/01/29/addressaccessdeniedexception-cause-and- solution.aspx – driis

4

Ninguno. Punto. Dll de 32 bits en proceso de 64 bits = no ir.

Lo que hago es ejecutar un proceso de envoltura de 32 bits y comunicarme con él usando WCF, al igual que usted. Puedo obligar al sistema operativo a ejecutar 32 bits.

Tengo una biblioteca principal (Tradex.Connectivity.Core), con la plataforma independiente .NET code. Tengo dos contenedores (Wrapper32.exe, Wapper64.exe) que comienzan y cargan el código independiente y luego cargan la clase (C++ administrado). Funciona de maravilla.

Casi es la única forma para mí: no puede cargar elementos de 32 y 64 bits.

+0

"Lo que hago es ejecutar un proceso de envoltura de 32 bits y comunicarme con él usando WCF, al igual que usted. Puedo forzar al sistema operativo a ejecutar 32 bits". ¿Cómo logró que su servicio WCF se ejecute en modo de 32 bits en un sistema operativo de 64 bits? Establecer el objetivo de la plataforma en x86 arroja BadImageFormatException y no he podido buscar una forma de evitarlo. – bufferz

+0

¿Por qué me importa? Quiero decir, WCF está basado en red de todos modos. Una vez que las cosas se serializan, ya no hay un modo de 32 o 64 bits. Ah, y yo auto-host - no wcfsvdhost, inicio mi propio hosting en mi exe. Solo un par de líneas de código. – TomTom

+0

Gracias TomTom, no sabía que usted podría alojar elementos de WCF fuera de los proyectos de plantillas de WCF. Ya que preguntaste "¿por qué me importa?" Debo señalar que, literalmente, no pude compilar un proyecto de plantilla de WCF de 32 bits que incluía una DLL de 32 bits. Solo la plantilla, sin embargo, funciona el autohosting. gracias de nuevo. – bufferz

1

Sé que esta respuesta podría ser un poco tarde, pero hace algún tiempo tuve el mismo problema (cargar un dll de 32 bits en un ensamblado AnyCPU en una máquina de 64 bits).

Como solución, escribí el LegacyWrapper. Básicamente consiste en un exe de contenedor de 32 bits cargando el dll deseado, comunicándose con su aplicación a través de Named Pipes.

Una llamada se vería así:

// Define delegate matching api function 
private delegate int GetSystemMetrics(int index); 

// Create new WrapperClient 
// Remember to ensure a call to the Dispose()-Method! 
using (var client = new WrapperClient()) 
{ 
    // Make calls providing library name, function name, and parameters 
    int x = (int)client.Invoke<GetSystemMetrics>("User32.dll", "GetSystemMetrics", new object[] { 0 }); 
    int y = (int)client.Invoke<GetSystemMetrics>("User32.dll", "GetSystemMetrics", new object[] { 1 }); 
} 

Para algunos detalles, puede hacer referencia a esta blog post.

Editar:Since Version 2.1, LegacyWrapper also supports loading 64bit DLLs from a 32bit process.

Cuestiones relacionadas