Исключение BadImageFormatException при загрузке 32-разрядной библиотеки DLL, целью является x86
У меня есть DLL (FreeType), который, безусловно, 32-битный (заголовок: IMAGE_FILE_MACHINE_I386).
Я хочу использовать его из кода С#, используя DllImport.
Цель моего приложения - x86, IntPtr.Size - 4, процесс - 32-разрядный.
Но я получаю BadImageFormatException (Исключение из HRESULT: 0x8007000B). Что может быть неправильным?
Конечно, я использую 64-разрядную Windows 7.
Ответы
Ответ 1
Из того, что я понимаю, сборка, специально построенная для x86 и работающая в 64-разрядной операционной системе, может загружать только библиотеки, созданные для x86, или будет выведено исключение BadImageFormatException. В 64-битной ОС сборка, созданная для любого процессора или x64, будет вызывать одно и то же исключение при попытке загрузить библиотеку x86.
Итак, предполагая, что ничего невероятно странного не происходит, я бы удостоверился, что вы настроили приложение для создания как x86, открыв свойства проекта и щелкнув вкладку "Построение". Убедитесь, что "Platform Target" установлен как "x86", а не любой CPU.
В качестве альтернативы вы можете попытаться найти 64-разрядную версию DLL для тестирования.
Ответ 2
Перекомпилируйте dll с опцией "Любой процессор" в Build → Platform.
![enter image description here]()
Ответ 3
ОК, похоже на ложное предупреждение. Это не было связано с долотостью, было просто другое DLL, которое не зависит от freetype. Однако сообщения об ошибках могут быть более полезными.
Ответ 4
Кроме того, для веб-приложений необходимо разрешить запуск 32-разрядных приложений в IIS 7. См. http://www.fishofprey.com/2009/04/badimageformatexception-in-iis-70-on-64.html
Ответ 5
Получена такая же ошибка при вызове 64-битной C Dll из С#. Мне пришлось вручную изменить С# Properties->Build->Platform target
с Any Cpu
на x64
. По-видимому, Any Cpu
иногда является NoCpu.
Ответ 6
У меня была аналогичная ошибка.
Я мог бы решить эту проблему, добавив ucrtbase.dll или ucrtbased.dll для отладки, а также vcruntime140.dll или vcruntime140d.dll для отладки в каталог исполняемого файла.
Я думаю, что 140 зависит от номера версии Visual Studio, которую вы используете.
ucrtbase.dll обычно лежит в C:\Windows\System32
.
vcruntime140.dll находится в C:\Program Files (x86)\Microsoft Visual Studio 14.0\Common7\IDE\Remote Debugger\x86\vcruntime140.dll
Вы можете найти более подробную информацию здесь: http://blogs.msdn.com/b/vcblog/archive/2015/03/03/introducing-the-universal-crt.aspx
Ответ 7
Вы можете попробовать проверить опцию "Свойства" → "Создать" → "Разрешить небезопасный код".
Ответ 8
Когда вы создаете собственное приложение /DLL с Visual Studio, он получает зависимость от "распространяемого" пакета для этой версии Visual Studio. Это содержит DLL, такие как msvcr100.dll
и msvcp100.dll
(для разных значений 100).
В моем случае я видел эти DLL файлы в каталоге Windows/system32
целевой машины, поэтому я думал, что все в порядке. Оказывается, эти DLL файлы были x64! Я понятия не имею, почему каталог с именем system32
содержит 64-разрядные библиотеки DLL. Поэтому я искал свой каталог Visual Studio 2010 для всего, что называется msvc*.dll
, и нашел версии x86 msvcr100.dll
и msvcp100.dll
. Я скопировал их на целевую машину (в месте, доступном из моего пути к программе), и все было хорошо.
Я надеюсь, что это поможет кому-то еще столкнуться с безумством Microsoft.
Ответ 9
У меня было такое же исключение в MS Visual С# Express 2010. Я проверил все файлы .dll и .exe с Dependency Walker и MiTeC EXE Explorer, все было построено для 32-битного!
В конце концов, это была следующая строка, отсутствующая в моем файле .csproj:
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'MY_CONFIG|x86'">
...
<PlatformTarget>x86</PlatformTarget>
...
</PropertyGroup>
Я не знаю, почему этого не было... Я предполагаю, что MS Visual С# Express 2010 не bugfree;)