548 votes

Comment corriger l'erreur de compilation de Visual Studio, "mismatch between processor architecture" ?

Je suis novice en matière de configuration de projets dans Visual Studio 2010, mais j'ai fait un peu d'expérience dans ce domaine. recherche et je n'arrive toujours pas à résoudre ce problème. J'ai une solution Visual Studio avec une DLL C++ faisant référence à la DLL C#. La DLL C# fait référence à quelques autres DLL, certaines dans mon projet et d'autres externes. Lorsque j'essaie de compiler la DLL C++, j'obtiens cet avertissement :

avertissement MSB3270 : Il y a eu un désaccord entre l'architecture du processeur du projet en cours de construction "MSIL" et l'architecture du processeur de la référence "[internal C# dll]", "x86".

Il me dit d'aller dans le Configuration Manager pour aligner mes architectures. La DLL C# est configurée avec une cible de plate-forme x86. Si j'essaie de changer cela en quelque chose d'autre, comme Any CPU, il se plaint parce que l'une des DLL externes il dépend de la plateforme cible x86.

Lorsque je regarde le Gestionnaire de configuration, la plate-forme de ma DLL C# est x86 et celle de mon projet C++ est Win32. Cela semble être la bonne configuration ; je ne veux certainement pas que la plate-forme de mon projet C++ soit définie sur x64, ce qui est la seule autre option présentée.

Qu'est-ce que je fais de mal ici ?

0 votes

Quelle est la plainte, spécifiquement, lorsque vous le changez en n'importe quel CPU ?

2 votes

Je n'ai pas assez d'informations pour faire une suggestion éclairée, mais faites un clic droit sur votre solution -> Project Build Order et assurez-vous que votre projet C# est construit avant le projet C++. Si ce n'est pas le cas, allez dans l'onglet Dépendances et faites savoir à VS que le projet C++ dépend du projet C#.

6 votes

Visual Studio est encore une fois merdique sur ce point. La plate-forme en haut de mon écran indique x64 mais l'avertissement indique que le projet en cours de construction est "MSIL". Donc Visual Studio me dit qu'il y a un décalage entre des pommes et des oranges alors que je n'utilise pas de pommes. Peut-on le renommer en Visual Stupido ?

604voto

David Sacks Points 1946

Cet avertissement semble avoir été introduit avec la nouvelle version bêta de Visual Studio 11 et .NET 4.5, bien que je suppose que cela aurait pu être possible avant.

D'abord, ce n'est vraiment qu'un avertissement. Il ne devrait rien faire si vous ne traitez que des dépendances x86. Microsoft essaie simplement de vous avertir lorsque vous déclarez que votre projet est compatible avec "Any CPU" mais que vous avez une dépendance sur un projet ou un assemblage .dll qui est soit x86 soit x64. Parce que vous avez une dépendance x86, techniquement votre projet n'est donc pas compatible avec "Any CPU". Pour que l'avertissement disparaisse, vous devez changer votre projet de "Any CPU" à "x86". C'est très facile à faire, voici les étapes.

  1. Allez dans l'élément de menu Build|Configuration Manager.
  2. Trouvez votre projet dans la liste, sous Plate-forme, il sera indiqué "Any CPU".
  3. Sélectionnez l'option " Any CPU " dans le menu déroulant, puis sélectionnez <New..>
  4. Dans cette boîte de dialogue, sélectionnez x86 dans le menu déroulant "New Platform" et assurez-vous que "Any CPU" est sélectionné dans le menu déroulant "Copy settings from".
  5. Appuyez sur OK
  6. Vous voudrez sélectionner x86 pour les configurations Debug et Release.

Cela fera disparaître l'avertissement et indiquera également que votre assemblage ou projet n'est plus compatible avec "Any CPU" mais qu'il est désormais spécifique au x86. Ceci est également applicable si vous construisez un projet 64 bit qui a une dépendance x64 ; vous devez simplement sélectionner x64 à la place.

Une autre remarque, les projets peuvent être compatibles avec "n'importe quelle unité centrale" s'il s'agit de projets purement .NET. Ce problème ne se pose que si vous introduisez une dépendance (dll d'un tiers ou votre propre projet géré en C++) qui cible une architecture de processeur spécifique.

3 votes

Je viens d'installer le RTW de Visual Studio 2012 et j'ai ouvert une solution 2010 préexistante et j'ai commencé à voir le même avertissement, donc c'est quelque chose qui existe toujours dans le RTW.

7 votes

Ceci étant dit, je pense que la réponse de David est correcte, cet avertissement vous fait savoir que votre application n'est pas vraiment "AnyCPU" et que vous rencontrerez des problèmes si vous la déployez sur la mauvaise architecture.

9 votes

Cela PEUT très bien faire mal à quelque chose. Un exe pour n'importe quel processeur se chargera en x64 sur un système d'exploitation 64 bits et sera incapable de charger des dlls x86. Donc, si vous dépendez d'une plate-forme particulière, vous devez vraiment définir votre plate-forme correctement.

163voto

Derik J. Palacino Points 843

Il s'agit d'un avertissement très tenace et, bien qu'il s'agisse d'un avertissement valide, il existe des cas où il ne peut être résolu en raison de l'utilisation de composants tiers et d'autres raisons. J'ai un problème similaire, sauf que l'avertissement est dû au fait que la plateforme de mon projet est AnyCPU et que je fais référence à une bibliothèque MS construite pour AMD64. Ce problème se pose dans Visual Studio 2010 et semble avoir été introduit par l'installation de VS2012 et de .Net 4.5.

Puisque je ne peux pas modifier la bibliothèque MS à laquelle je fais référence, et puisque je sais que mon environnement de déploiement cible ne sera jamais que 64 bits, je peux ignorer ce problème sans risque.

Et l'avertissement ? Microsoft a posté en réponse à un rapport Connect qu'une option consiste à désactiver cet avertissement. Vous ne devez le faire que si vous êtes très conscient de l'architecture de votre solution, que vous comprenez parfaitement votre cible de déploiement et que vous savez que ce n'est pas vraiment un problème en dehors de l'environnement de développement.

Vous pouvez modifier votre fichier de projet et ajouter ce groupe de propriétés et ce paramètre pour désactiver l'avertissement :

<PropertyGroup>
  <ResolveAssemblyWarnOrErrorOnTargetArchitectureMismatch>None</ResolveAssemblyWarnOrErrorOnTargetArchitectureMismatch>
</PropertyGroup>

1 votes

La seule autre référence officielle de MS à cette solution que j'ai vue se trouve dans le document Fichier Readme de Microsoft .NET Framework 4.5 RC . Étrangement, elle a été supprimée du fichier Readme de la RTM.

4 votes

Cela fonctionne, mais pas pour une variante de l'avertissement : "Referenced assembly ... targets a different processor than the application". Ce serait bien s'il y avait un paramètre similaire pour cet avertissement ?

9 votes

"La plate-forme de mon projet est AnyCPU et je fais référence à une bibliothèque MS construite pour AMD64"... C'est FAUX. Puisque votre déploiement cible est toujours 64 bits, vous pouvez définir votre plate-forme sur x64, ce qui donne une erreur plus appropriée si votre hypothèse 64 bits est violée, et empêche également l'avertissement.

73voto

Gustavo Mori Points 2649

Une bonne règle de base est "DLLs ouvertes, EXEs fermés", c'est-à-dire :

  • EXE cible le système d'exploitation, en spécifiant x86 ou x64.
  • DLLs sont laissés ouverts (c'est-à-dire AnyCPU) afin qu'ils puissent être instanciés dans un processus 32 bits ou 64 bits.

Lorsque vous construisez un EXE en tant que AnyCPU, tout ce que vous faites est de reporter la décision sur le bitness du processus à utiliser au système d'exploitation, qui va JIT l'EXE à son goût. En d'autres termes, un système d'exploitation x64 créera un processus 64 bits, un système d'exploitation x86 créera un processus 32 bits.

Construire les DLL en tant que AnyCPU les rend compatibles avec les deux processus.

Pour en savoir plus sur les subtilités du chargement des assemblages, voir ici . Le résumé se lit comme suit :

  • AnyCPU - se charge en tant qu'assemblage x64 ou x86, selon le processus qui l'invoque.
  • x86 - se charge en tant qu'assemblage x86 ; ne se charge pas à partir d'un processus x64
  • x64 - se charge en tant qu'assemblage x64 ; ne se charge pas à partir d'un processus x86

4 votes

Cette règle me paraît logique. Mais considérez la situation suivante : Native.dll (x64) utilisé par NetA.dll (Any CPU) utilisé par NetB.dll (Any CPU) utilisé par App1.exe (x64). Il n'y a pas de réel problème ici, mais la compilation de NetA.dll me donne l'avertissement. OK, puisque cette assemblée dépend directement de Native.dll, je pourrais la marquer comme x64 également. Mais alors la compilation de NetB.dll me donne un avertissement. Je veux garder NetB.dll comme "Any CPU" parce qu'il s'agit d'un assemblage commun utilisé dans une application différente, pure-dot-net. J'en conclus que ma seule option est de supprimer/ignorer l'avertissement. Oui ?

2 votes

En raison de la dépendance à l'égard de Native.dll, toute votre lignée d'applications/assemblages est désormais x64, que vous supprimiez ou non l'avertissement. Bien que la suppression fonctionne dans votre scénario, des situations étranges pourraient survenir à l'avenir. Par exemple, 1) l'assemblage NetB est utilisé dans un environnement x86, où Nativex64 ne sera pas chargé, ou 2) votre client veut une version x86 de App1.exe, et vous compilez sans problème, puisque NetB est marqué comme n'importe quel CPU, mais à nouveau, Nativex64 en haut de la pile ne sera pas chargé.

0 votes

Bien que la règle de Gustavo soit un bon principe, elle ne peut pas être utilisée pour le problème spécifique posé dans cette question car le projet a déjà une dépendance sur un assemblage tiers qui n'a pas suivi la règle (c'est x86, pas AnyCPU). Par conséquent, tant que la dépendance existe, toute la chaîne de projets doit cibler x86 et rien d'autre.

24voto

Hans Passant Points 475940

La DLL C# est configurée avec une plateforme cible x86.

C'est en quelque sorte le problème, une DLL n'a pas vraiment le droit de choisir ce que sera le bitness du processus. C'est entièrement déterminé par le projet EXE, c'est le premier assemblage qui est chargé donc sa cible Platform est celle qui compte et définit le bitness pour le processus.

Les DLL n'ont pas le choix, elles doivent être compatibles avec le débit binaire du processus. Si elles ne le sont pas, vous obtiendrez un grand Kaboom avec une BadImageFormatException lorsque votre code essaiera de les utiliser.

Une bonne sélection pour les DLLs est donc AnyCPU afin qu'elles fonctionnent dans les deux cas. Cela a beaucoup de sens pour les DLLs C#, elles faire travailler dans les deux sens. Mais bien sûr, pas votre DLL C++/CLI en mode mixte, elle contient du code non géré qui ne peut fonctionner correctement que lorsque le processus s'exécute en mode 32 bits. Vous peut pour que le système de construction génère des avertissements à ce sujet. C'est exactement ce que vous avez obtenu. Juste des avertissements, ça se construit toujours correctement.

Il suffit d'évacuer le problème. Définissez la cible Platform du projet EXE sur x86, cela ne fonctionnera pas avec un autre paramètre. Et gardez tous les projets DLL à AnyCPU.

1 votes

Donc, pour être clair : je ne construis pas l'EXE, je construis une DLL à exécuter avec l'EXE de quelqu'un d'autre. Le fait de changer la cible de la plate-forme des DLL C# pour Any CPU ne fait pas disparaître l'avertissement. Je me demande s'il s'agit d'un cas de connect.microsoft.com/VisualStudio/feedback/details/728901/ -- J'ignorerais l'avertissement lui-même mais en fait, l'EXE est capable de charger la DLL C# mais pas la DLL C++, donc je pense que c'est un vrai problème.

0 votes

Utilisez-vous en fait VS2010 ? De plus, il n'était pas du tout clair que vous ne pouviez pas charger la DLL C++/CLI. Quel est le diagnostic ? Mettez à jour vos questions avec ces informations essentielles.

0 votes

Je n'avais pas posté de message sur l'échec de la charge parce que je n'étais pas sûr à 100% qu'elle était connectée, et en déboguant davantage, il s'avère qu'elle ne l'était pas. J'utilise VS2010. Mise à jour du texte de la question. Désolé pour la confusion

2voto

Jonathan DeCarlo Points 1513

Pour les projets C#, la cible de x86 fait ce à quoi elle ressemble. Elle indique que cet assemblage ne prend en charge que les architectures x86. De même pour x64. D'un autre côté, n'importe quelle unité centrale indique que je ne me soucie pas de l'architecture, je supporte les deux. Donc, les 2 questions suivantes sont (1) quelle est la configuration de l'exécutable qui utilise ces dlls ? et (2) quelle est la cible de x86 ? bitness de votre OS/ordinateur ? La raison pour laquelle je pose la question est que si votre exécutable est compilé pour fonctionner en 64 bits, alors il a BESOIN que toutes les dépendances soient également capables de fonctionner en mode 64 bits. Votre assemblage Any CPU devrait pouvoir être chargé, mais peut-être fait-il référence à une autre dépendance qui ne peut fonctionner qu'en configuration x86. Vérifiez toutes les dépendances et les dépendances des dépendances pour vous assurer que tout est soit "Any CPU" soit "x64" si vous prévoyez d'exécuter l'exécutable en mode 64 bits. Sinon, vous aurez des problèmes.

À bien des égards, Visual Studio ne facilite pas la compilation d'un mélange d'assemblages dépendant de n'importe quel CPU et de diverses architectures. C'est faisable, mais cela nécessite souvent qu'un assemblage qui serait autrement "Any CPU" doive être compilé séparément pour x86 et x64 parce qu'une certaine dépendance d'une dépendance quelque part a deux versions.

0 votes

La configuration de l'exécutable est-elle pertinente puisque j'obtiens un échec juste en essayant de construire les DLLs ? (Il s'agit pourtant de x86.) Mon ordinateur est x64.

2 votes

C'est l'exécutable qui détermine ce que bitness sera utilisé. Si l'exécutable est exécuté en x64, tout ce qu'il charge (directement ou indirectement) doit être x64 ou Any CPU. Si l'exécutable est exécuté en x86, tout ce qu'il charge (directement ou indirectement) doit être x86 ou n'importe quelle unité centrale.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X