c# - bad image format exception
BadImageFormatException al cargar archivos DLL de 32 bits, el destino es x86 (11)
Además, para las necesidades de la aplicación web, resuelva ejecutar aplicaciones de 32 bits en IIS 7. Consulte http://www.fishofprey.com/2009/04/badimageformatexception-in-iis-70-on-64.html
Tengo un DLL (FreeType) que ciertamente es de 32 bits (header: IMAGE_FILE_MACHINE_I386).
Quiero usarlo desde el código C #, usando DllImport.
El objetivo de mi aplicación es x86, IntPtr.Size es 4, el proceso es de 32 bits.
Pero obtengo BadImageFormatException (Excepción de HRESULT: 0x8007000B). ¿Qué puede estar mal?
Por supuesto que uso Windows 7 de 64 bits.
Cuando compila una aplicación / DLL nativa con Visual Studio, obtiene una dependencia del paquete "redistribuible" para esa versión de Visual Studio. Que contiene DLL como msvcr100.dll
y msvcp100.dll
(para varios valores de 100).
En mi caso, había visto esas DLL en el directorio Windows/system32
la máquina de destino, así que pensé que todo estaba bien. ¡Resulta que esas DLL eran x64! No tengo idea de por qué un directorio llamado system32
contiene archivos DLL de 64 bits. Así que busqué en mi directorio de Visual Studio 2010 todo lo que se llama msvc*.dll
, y encontré las versiones x86 de msvcr100.dll
y msvcp100.dll
. Los copié a la máquina de destino (en un lugar accesible desde la ruta de mi programa) y todo estaba bien.
Espero que esto ayude a alguien más enfrentado con la locura de Microsoft.
OK, parece una alerta falsa. No estaba relacionado con bitness, solo faltaba otra DLL de la que dependa freetype. Sin embargo, los mensajes de error podrían ser más útiles.
Por lo que entiendo, un ensamblado específicamente desarrollado para x86 y ejecutado en un sistema operativo de 64 bits solo puede cargar bibliotecas creadas para x86 o se lanzará una BadImageFormatException. En un sistema operativo de 64 bits, un ensamblado creado para Cualquier CPU o x64 emitirá la misma excepción cuando intente cargar una biblioteca x86.
Entonces, suponiendo que algo increíblemente extraño esté sucediendo, me aseguraré de que hayas configurado tu aplicación para que se construya como x86 abriendo las propiedades del proyecto y haciendo clic en la pestaña Generar. Asegúrese de que ''Platform Target'' esté configurado como ''x86'' y no como cualquier CPU.
Alternativamente, podría intentar encontrar una versión de 64 bits de la DLL para realizar pruebas.
Puede intentar marcar la opción "Propiedades" -> "Crear" -> "Permitir código no seguro".
Recompile el dll con la opción "Cualquier CPU" en Build -> Platform.
Sospecho que la causa común de esta excepción ha cambiado en los 8 años desde que se formuló la pregunta por primera vez. En mi configuración usando VS 2017, encontré que desmarcar "Preferir 32 bits" resolvió el problema:
Desmarque "Preferir 32 bits" en las opciones de compilación
Esto hizo que mi DLL de 64 bits creada desde C ++ se cargara correctamente. Por el contrario, si marca esta opción, las DLL de 32 bits se cargarán correctamente.
Tuve la misma Excepción en MS Visual C # Express 2010. Comprobé todos los archivos .dll y .exe de compilación con Dependency Walker y MiTeC EXE Explorer, ¡todo fue compilación de 32 bits!
Al final, faltaba la siguiente línea en mi archivo .csproj:
<PropertyGroup Condition="''$(Configuration)|$(Platform)'' == ''MY_CONFIG|x86''">
...
<PlatformTarget>x86</PlatformTarget>
...
</PropertyGroup>
No sé por qué faltaba ... Supongo que MS Visual C # Express 2010 no está libre de errores;)
Tuve un error similar. Podría resolverlo agregando ucrtbase.dll o ucrtbased.dll para la depuración, así como vcruntime140.dll o vcruntime140d.dll para la depuración en el directorio del ejecutable. Creo que el 140 depende del número de versión de Visual Studio que esté usando.
ucrtbase.dll generalmente se encuentra en C:/Windows/System32
. vcruntime140.dll se encuentra en C:/Program Files (x86)/Microsoft Visual Studio 14.0/Common7/IDE/Remote Debugger/x86/vcruntime140.dll
Puede encontrar más información aquí: http://blogs.msdn.com/b/vcblog/archive/2015/03/03/introducing-the-universal-crt.aspx
usa Propiedades en el proyecto C # y cambia el "Objetivo de la plataforma" a x64. enter image description here
Obtuve el mismo error al llamar a un C Dll de 64 bits desde C #. Tuve que cambiar manualmente C # Properties->Build->Platform target
desde Any Cpu
a x64
. Aparentemente, Any Cpu
es a veces NoCpu.