2010-12-08 31 views
7

Me he encontrado con un problema del que estoy bastante seguro de que sé la respuesta, pero supuse que al menos preguntaría si había algo de "magia". bullet "eso podría salvarme un gran dolor de cabeza".Mezcla de 32 bits y 64 bits P/Invoca

Aquí está la vista de alto nivel.

Tengo una aplicación administrada. Esta aplicación interactúa con hardware a través de bibliotecas de terceros de diferentes proveedores. Tengo control total sobre la aplicación administrada que consume y cero control sobre las bibliotecas de API de hardware.

El proveedor A proporciona solo un SDK nativo de 32 bits. Para permitirnos usarlo en sistemas de 64 bits, marcamos la aplicación para que se ejecute en modo de 32 bits. Todo estuvo bien.

Ahora nos estamos integrando con el proveedor B, que proporciona bibliotecas API nativas de 64 bits en máquinas de 64 bits. La DLL nativa de 32 bits del proveedor B no funcionará en un sistema de 64 bits (lo intenté). Si construyo un arnés de prueba corriendo como 64-bit o AnyCPU, funciona bien. Si lo marqué como de 32 bits, falla en las llamadas P/Invoke.

Parece que el hardware del proveedor A y del proveedor B se van a excluir mutuamente en las PC de 64 bits, pero me pregunto si alguien tiene sugerencias sobre cómo solucionarlo.

Respuesta

6

El problema no es .NET o P/Invoke. Es un problema de sistema operativo. Un proceso de 64 bits solo puede cargar archivos DLL de 64 bits. Un proceso de 32 bits solo puede cargar archivos DLL de 32 bits. La mágica capa de Windows-on-Windows (o WoW) que permite que las aplicaciones de 32 bits se ejecuten en Windows de 64 bits existe entre el proceso en modo de usuario (EXE y DLL) y el kernel. No hay forma de ejecutar una DLL de 32 bits dentro de un proceso de 64 bits. La capa de WoW existe debajo de eso. (Básicamente, WoW es un contenedor de 32 bits alrededor de la API de Win32 de 64 bits, que reúne las llamadas de datos y funciones entre el mundo de 32 bits del proceso y el mundo de 64 bits del sistema operativo).

Su mejor/only es ejecutar sus componentes de 32 y 64 bits en procesos separados y usar alguna forma de IPC para comunicarse. Esto tiene el beneficio adicional de desacoplar su aplicación principal de los componentes de terceros potencialmente inestables. Si un componente de terceros se bloquea o se comporta mal, es simplemente una cuestión de reiniciar el proceso que contiene ese componente.

+0

Ya lo hemos secuestrado en un dominio de aplicación anotehr así que la seguridad está bien. Moverlo a otro proceso es agregar la complejidad de la interfaz que esperábamos evitar, pero parece que eso o abandonar el hardware del Proveedor A. – ctacke

+0

Es bueno que lo haya secuestrado en otro AppDomain. Sin embargo, un AppDomain solo proporciona seguridad entre los componentes del código administrado. El código no administrado puede tomar alegremente un puntero malo y comenzar a arrojar basura en todo el espacio de la memoria de proceso, independientemente de AppDomain. Es posible que desee considerar IPC a través de archivos mapeados en memoria o una técnica similar para que los componentes de terceros no puedan arruinar su aplicación. :) –

1

Puede hacer un proceso separado de 32 bits para interactuar con el Proveedor A, luego comunicarse con él usando WCF.

+0

Sí, estaba tratando de evitar eso, pero podría ser el único recurso. – ctacke

0

Esperemos que alguien pueda sugerir una mejor alternativa, pero quizás podría envolver una de las bibliotecas (la que tenga la conexión de ancho de banda más baja) en un proceso separado y luego comunicarse con ella (por ejemplo, mediante sockets).

1

Dado que no puede cargar imágenes de 32 y 64 bits en el mismo proceso, deberá usar una solución multiproceso.

Cuestiones relacionadas