J'ai un DLL (FreeType) qui est certainement 32 bits (en-tête: IMAGE_FILE_MACHINE_I386).
Je veux l'utiliser à partir de code C #, en utilisant DllImport.
La cible de mon application est x86, IntPtr.Size est 4, le processus est 32 bits.
Mais je reçois BadImageFormatException (exception de HRESULT: 0x8007000B). Qu'est-ce qui ne va pas?
Bien sûr, j'utilise Windows 7 64 bits.
D'après ce que j'ai compris, un assemblage spécialement conçu pour x86 et s'exécutant dans un système d'exploitation 64 bits ne peut charger que des bibliothèques construites pour x86 ou une exception BadImageFormatException. Dans un système d'exploitation 64 bits, un assemblage conçu pour Any CPU ou x64 générera la même exception lors du chargement d'une bibliothèque x86.
Donc, en supposant que rien d'incroyablement étrange ne se passe, je m'assurerais que vous avez configuré votre application pour générer en tant que x86 en ouvrant les propriétés du projet et en cliquant sur l'onglet Construire. Assurez-vous que «Plate-forme cible» est défini sur «x86» et non sur Tout processeur.
Vous pouvez également essayer de trouver une version 64 bits de DLL à des fins de test.
Recompilez la dll avec l'option "N'importe quel processeur" dans Build -> Platform.
OK, cela ressemble à une fausse alerte. Ce n'était pas lié au bitness, il ne manquait plus que DLL dont dépend freetype. Cependant, les messages d'erreur pourraient être plus utiles.
En outre, pour les besoins des applications Web, résolvez d'exécuter des applications 32 bits dans IIS 7. Voir http://www.fishofprey.com/2009/04/badimageformatexception-in-iis-70-on-64 .html
Vous obtenez la même erreur lorsque vous appelez une DLL C 64 bits à partir de C #. J'ai dû modifier manuellement C # Properties->Build->Platform target
de Any Cpu
à x64
. Apparemment, Any Cpu
est parfois NoCpu.
J'ai eu une erreur similaire . Je pourrais le résoudre en ajoutant le ucrtbase.dll ou ucrtbased.dll pour le débogage ainsi que le vcruntime140.dll ou vcruntime140d.dll pour le débogage dans le répertoire de l'exécutable. Je pense que le 140 dépend du numéro de version de Visual Studio que vous utilisez.
ucrtbase.dll se trouve généralement dans C:\Windows\System32
. vcruntime140.dll se trouve dans C:\Program Files (x86)\Microsoft Visual Studio 14.0\Common7\IDE\Remote Debugger\x86\vcruntime140.dll
Vous pouvez trouver plus d'informations ici: http://blogs.msdn.com/b/vcblog/archive/2015/03/03/introducing-the-universal-crt.aspx
Lorsque vous générez quelque chose dans une application/DLL native avec Visual Studio, il devient dépendant du package "redistribuable" pour cette version de Visual Studio. Qui contient des DLL comme msvcr100.dll
et msvcp100.dll
(pour différentes valeurs de 100).
Dans mon cas, j'avais vu ces DLL dans le répertoire Windows/system32
de la machine cible, alors je pensais que tout allait bien. Il s'avère que ces DLL étaient x64! Je ne sais pas pourquoi un répertoire appelé system32
contient des DLL 64 bits. J'ai donc cherché dans mon répertoire Visual Studio 2010 tout ce qui est nommé msvc*.dll
et trouvé des versions x86 de msvcr100.dll
et msvcp100.dll
. J'ai copié ceux-ci sur la machine cible (dans un endroit accessible depuis le chemin de mon programme) et tout allait bien.
J'espère que cela aidera quelqu'un d'autre confronté à la folie pure de Microsoft.
Vous pouvez essayer de cocher l'option "Propriétés" -> "Construire" -> "Autoriser le code non sécurisé".
vous utilisez les propriétés du projet C # et modifiez "Cible de la plateforme" en x64 . entrez la description de l'image ici
Je suppose que la cause commune de cette exception a changé au cours des 8 années écoulées depuis que la question a été posée pour la première fois. Sur ma configuration utilisant VS 2017, j'ai constaté que le fait de décocher l'option "Préférer 32 bits" résolvait le problème:
Décochez la case "Préférer 32 bits" dans les options de construction
Cela a permis à ma DLL version 64 bits construite à partir de C++ de se charger correctement. Inversement, cocher cette option devrait permettre aux DLL 32 bits de se charger correctement.