Hoe los ik de Visual Studio-compileerfout, “mismatch tussen processorarchitectuur” op?

Ik ben nieuw in de projectconfiguratie in Visual Studio 2010, maar ik heb wat onderzoeken kan dit probleem nog steeds niet helemaal achterhalen. Ik heb een Visual Studio-oplossing met een C++ DLL die verwijst naar de C# DLL. De C# DLL verwijst naar een paar andere DLL’s, sommige binnen mijn project en sommige extern. Wanneer ik de C++ DLL probeer te compileren, krijg ik deze waarschuwing:

waarschuwing MSB3270: er was een mismatch tussen de processorarchitectuur van het project dat wordt gebouwd “MSIL” en de processorarchitectuur van de referentie “[internal C# dll]”, “x86”.

Het vertelt me ​​dat ik naar Configuration Manager moet gaan om mijn architecturen uit te lijnen. De C# DLL is ingesteld met platformdoel x86. Als ik dit probeer te veranderen in iets anders, zoals Elke CPU, klaagt het omdat een van de externe DLL’s waarvan hetafhankelijk is, platformdoel x86 heeft.

Als ik naar Configuration Manager kijk, wordt het platform voor mijn C# DLL weergegeven als x86 en voor mijn C++-project als Win32. Dit lijkt de juiste opstelling; ik wil zeker niet dat het platform voor mijn C++-project op x64 staat, wat de enige andere optie is die wordt aangeboden.

Wat doe ik hier verkeerd?


Antwoord 1, autoriteit 100%

Deze waarschuwing lijkt te zijn geïntroduceerd met de nieuwe Visual Studio 11 Beta en .NET 4.5, hoewel ik veronderstel dat dit eerder mogelijk was.

Ten eerste is het eigenlijk gewoon een waarschuwing. Het zou geen kwaad mogen als je alleen met x86-afhankelijkheden te maken hebt. Microsoft probeert u alleen maar te waarschuwen wanneer u aangeeft dat uw project compatibel is met “Elke CPU”, maar u afhankelijk bent van een project of een .dll-assembly die x86 of x64 is. Omdat je een x86-afhankelijkheid hebt, is je project technisch gezien daarom niet “Elke CPU”-compatibel. Om de waarschuwing te laten verdwijnen, moet u uw project eigenlijk wijzigen van “Elke CPU” in “x86”. Dit is heel gemakkelijk te doen, hier zijn de stappen.

  1. Ga naar het menu-item Build|Configuration Manager.
  2. Zoek uw project in de lijst, onder Platform staat “Elke CPU”
  3. Selecteer de optie “Elke CPU” in de vervolgkeuzelijst en selecteer vervolgens <New..>
  4. Selecteer in dat dialoogvenster x86 in de vervolgkeuzelijst ‘Nieuw platform’ en zorg ervoor dat ‘Elke CPU’ is geselecteerd in de vervolgkeuzelijst ‘Instellingen kopiëren van’.
  5. Klik op OK
  6. U zult x86 willen selecteren voor zowel de Debug- als de Release-configuraties.

Hierdoor verdwijnt de waarschuwing en wordt ook aangegeven dat uw assembly of project nu niet langer “Elke CPU”-compatibel is, maar nu x86-specifiek. Dit is ook van toepassing als u een 64-bits project bouwt met een x64-afhankelijkheid; je zou in plaats daarvan gewoon x64 selecteren.

Nog een opmerking: projecten kunnen compatibel zijn met “Elke CPU”, meestal als het pure .NET-projecten zijn. Dit probleem doet zich alleen voor als u een afhankelijkheid introduceert (3e partij dll of uw eigen door C++ beheerde project) die gericht is op een specifieke processorarchitectuur.


Antwoord 2, autoriteit 27%

Dit is een zeer hardnekkige waarschuwing en hoewel het een geldige waarschuwing is, zijn er enkele gevallen waarin het niet kan worden opgelost vanwege het gebruik van componenten van derden en andere redenen. Ik heb een soortgelijk probleem, behalve dat de waarschuwing is omdat mijn projectplatform AnyCPU is en ik verwijs naar een MS-bibliotheek die is gebouwd voor AMD64. Dit zit trouwens in Visual Studio 2010 en lijkt geïntroduceerd te zijn door de installatie van VS2012 en .Net 4.5.

Aangezien ik de MS-bibliotheek waarnaar ik verwijs, niet kan wijzigen en aangezien ik weet dat mijn doelimplementatieomgeving altijd maar 64-bits zal zijn, kan ik dit probleem gerust negeren.

Hoe zit het met de waarschuwing? Microsoft heeft gepost in reactie op een Connect-rapportdat een optie is om die waarschuwing uit te schakelen. U moet dit alleen doen als u goed op de hoogte bent van uw oplossingsarchitectuur en uw implementatiedoel volledig begrijpt en weet dat het niet echt een probleem is buiten de ontwikkelomgeving.

U kunt uw projectbestand bewerken en deze eigenschappengroep en instelling toevoegen om de waarschuwing uit te schakelen:

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

Antwoord 3, autoriteit 12%

Een goede vuistregel is “open DLL’s, gesloten EXE’s”, dat wil zeggen:

  • EXEricht zich op het besturingssysteem door x86 of x64 op te geven.
  • DLL’sworden opengelaten (d.w.z. AnyCPU), zodat ze kunnen worden geïnstantieerd binnen een 32-bits of een 64-bits proces.

Als je een EXE bouwt als AnyCPU, is het enige wat je doet de beslissing over de te gebruiken procesbitness uitstellen naar het besturingssysteem, waardoor de EXE naar zijn wens wordt JIT. Dat wil zeggen, een x64-besturingssysteem maakt een 64-bits proces, een x86-besturingssysteem een ​​32-bits proces.

DLL’s bouwen als AnyCPU maakt ze compatibel met beide processen.

Voor meer informatie over de subtiliteiten van het laden van assembly’s, zie hier. De samenvatting leest ongeveer als volgt:

  • AnyCPU– laadt als x64- of x86-assembly, afhankelijk van het aanroepproces
  • x86– laadt als x86-assembly; wordt niet geladen vanuit een x64-proces
  • x64– laadt als x64-assembly; wordt niet geladen vanuit een x86-proces

Antwoord 4, autoriteit 4%

De C# DLL is ingesteld met platformdoel x86

Dat is een beetje het probleem, een DLL kan eigenlijk niet kiezen wat de bitness van het proces zal zijn. Dat wordt volledig bepaald door het EXE-project, dat is de eerste assembly die wordt geladen, dus de Platform-doelinstelling is degene die telt en de bitness voor het proces instelt.

De DLL’s hebben geen keus, ze moeten compatibel zijn met de procesbitness. Als dat niet het geval is, krijgt u een grote Kaboom met een BadImageFormatException wanneer uw code ze probeert te gebruiken.

Dus een goede keuze voor de DLL’s is AnyCPU, dus ze werken hoe dan ook. Dat is heel logisch voor C# DLL’s, ze werkenhoe dan ook. Maar zeker, niet uw C++/CLI-DLL met gemengde modus, het bevat onbeheerde code die alleen goed kan werken als het proces in 32-bits modus wordt uitgevoerd. Je kunthet bouwsysteem zover krijgen om waarschuwingen hierover te genereren. Dat is precies wat je hebt. Gewoon waarschuwingen, het bouwt nog steeds goed op.

Pak het probleem gewoon aan. Stel het Platform-doel van het EXE-project in op x86, het zal niet werken met een andere instelling. En bewaar alle DLL-projecten op AnyCPU.


Antwoord 5

Ik kreeg dezelfde waarschuwing toen ik dit deed:

  1. project uitladen
  2. projecteigenschappen bewerken, bijv. .csproj
  3. voeg de volgende tag toe:

    <PropertyGroup>
        <ResolveAssemblyWarnOrErrorOnTargetArchitectureMismatch>
            None
        </ResolveAssemblyWarnOrErrorOnTargetArchitectureMismatch>
    </PropertyGroup>
    
  4. Herlaad het project


Antwoord 6

Ik had vandaag dit probleem en alleen kijken naar de bouwconfiguraties in Visual Studio hielp niet omdat het elke CPU liet zien voor zowel het project dat niet aan het bouwen was als het project waarnaar wordt verwezen.

Ik keek toen in de csproj van het project waarnaar wordt verwezen en vond dit:

<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<PlatformTarget>x64</PlatformTarget>

Op de een of andere manier is dit PlatformTarget toegevoegd tijdens een configuratiewijziging en de IDE leek het niet te zien.

Het verwijderen van deze regel uit het project waarnaar wordt verwezen, loste mijn probleem op.


Antwoord 7

Als uw C#-DLL op x86 gebaseerde afhankelijkheden heeft, moet uw DLL zelf x86 zijn. Ik zie daar niet echt een oplossing voor. VS klaagt over het veranderen naar (bijvoorbeeld) x64 omdat een 64-bits uitvoerbaar bestand geen 32-bits bibliotheken kan laden.

Ik ben een beetje in de war over de configuratie van het C++-project. Het waarschuwingsbericht dat voor de build werd geleverd, suggereert dat het was gericht op AnyCPU, omdat het meldde dat het platform waarop het was gericht [MSIL] was, maar u gaf aan dat de configuratie voor het project eigenlijk Win32 was. Een native Win32-app zou de MSIL niet moeten betrekken, hoewel het waarschijnlijk CLR-ondersteuning moet hebben ingeschakeld als het communiceert met een C#-bibliotheek. Dus ik denk dat er een paar hiaten zijn aan de informatiekant.

Mag ik u met respect vragen om de exacte configuratie van de projecten en hoe ze met elkaar samenhangen, door te nemen en wat meer details te posten? Help indien mogelijk graag verder.


Antwoord 8

Naast het antwoord van David Sacks, moet u mogelijk ook naar het tabblad Buildvan de Project Propertiesgaan en Platform Targetinstellen op x86voor het project dat je deze waarschuwingen geeft. Hoewel je dit misschien zou verwachten, lijkt deze instelling niet perfect gesynchroniseerd te zijn met de instelling in de configuratiemanager.


Antwoord 9

Gebruik https://docs. microsoft.com/en-us/visualstudio/msbuild/customize-your-build#directorybuildprops-example:

  • voeg een Directory.Build.props-bestand toe aan uw oplossingsmap
  • plak dit erin:
<Project>
 <PropertyGroup>
   <ResolveAssemblyWarnOrErrorOnTargetArchitectureMismatch>None</ResolveAssemblyWarnOrErrorOnTargetArchitectureMismatch>
 </PropertyGroup>
</Project>

Antwoord 10

Voor C#-projecten doet het doel van x86 wat het klinkt. Er staat dat deze assembly alleen x86-architecturen ondersteunt. Zo ook voor x64. Elke CPU daarentegen zegt dat het me niet kan schelen welke architectuur, ik steun beide. Dus de volgende 2 vragen zijn (1) wat is de configuratie van het uitvoerbare bestand dat deze dll’s gebruikt? en (2) wat is de bitnessvan uw besturingssysteem/computer? De reden dat ik het vraag, is dat als je uitvoerbare bestand is gecompileerd om in 64-bit te draaien, het alle afhankelijkheden NODIG HEEFT om ook in 64-bits modus te kunnen draaien. Je Any CPU-assembly zou moeten kunnen worden geladen, maar misschien verwijst het naar een andere afhankelijkheid die alleen in x86-configuratie kan worden uitgevoerd. Controleer alle afhankelijkheden en afhankelijkheden van afhankelijkheden om er zeker van te zijn dat alles “Elke CPU” of “x64” is als u van plan bent het uitvoerbare bestand in 64-bits modus uit te voeren. Anders heb je problemen.

In veel opzichten maakt Visual Studio het samenstellen van een combinatie van Elke CPU en verschillende architectuurafhankelijke assemblages niet eenvoudig. Het is te doen, maar het vereist vaak dat een assembly die anders “Elke CPU” zou zijn, afzonderlijk moet worden gecompileerd voor x86 en x64, omdat ergens een afhankelijkheid van een afhankelijkheid twee versies heeft.


Antwoord 11

Ik heb eerder een soortgelijk probleem gehad, met name bij het toevoegen van een testoplossing aan een bestaande x64-oplossing, zoals SharePoint. In mijn geval lijkt het te maken te hebben met het feit dat bepaalde projectsjablonen standaard als bepaalde platforms worden toegevoegd.

Dit is de oplossing die vaak voor mij werkt: stel alles in op het juiste platform in Configuration Manager (de actieve vervolgkeuzelijst voor configuratie, zegt Debug normaal gesproken, is een goede manier om er te komen) en projectplatform (in projecteigenschappen ), vervolgens bouwen en vervolgens alles terugzetten naar AnyCPU. Soms moet ik enkele afhankelijkheden verwijderen en opnieuw toevoegen (DLL’s in de eigenschappen van elk project) en soms moet de “Tests uitvoeren in 32-bits of 64-bits proces” (dubbelklik op Local.testsettings en ga naar Hosts) worden gewijzigd.

Het lijkt mij dat dit gewoon iets instellen en dan weer terugzetten is, maar er is waarschijnlijk meer aan de hand achter de schermen dat ik niet zie. In het verleden heeft het voor mij echter redelijk consistent gewerkt.


Antwoord 12

Voor mijn project moet ik kunnen bouwen naar zowel x86 als x64. Het probleem hiermee is dat wanneer je referenties toevoegt terwijl je de ene gebruikt, het klaagt wanneer je de andere bouwt.

Mijn oplossing is om de *.csproj-bestanden handmatig te bewerken, zodat regels als deze:

<Reference Include="MyLibrary.MyNamespace, Version=1.0.0.0, Culture=neutral, processorArchitecture=x86"/>
<Reference Include="MyLibrary.MyNamespace, Version=1.0.0.0, Culture=neutral, processorArchitecture=AMD64"/>
<Reference Include="MyLibrary.MyNamespace, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL"/>

wijzig dit:

<Reference Include="MyLibrary.MyNamespace, Version=1.0.0.0, Culture=neutral"/>

Antwoord 13

Ik had een soortgelijk probleem, het werd veroorzaakt door MS UNIT Test DLL. Mijn WPF-toepassing is gecompileerd als x86, maar unit-test DLL (verwezen EXE-bestand) als “Elke CPU”. Ik heb de unit-test-DLL gewijzigd om te worden gecompileerd voor x86 (hetzelfde als EXE) en het werd opnieuw opgelost.


Antwoord 14

Je kunt deze waarschuwing ook krijgen voor MS Fakes-assemblages, wat niet zo eenvoudig op te lossen is omdat de f.csproj op commando is gebouwd. Gelukkig de nep-xml kun je het daar toevoegen .


Antwoord 15

Ik had een soortgelijke waarschuwing in mijn build. Mijn projecten waren ingesteld op .NET 4.5, op de buildserver was de Windows 8.1 SDK (voor .NET 4.5.1) geïnstalleerd. Na het updaten van mijn projecten naar target .NET 4.5.1 (was geen probleem voor mij, was voor een geheel nieuwe applicatie), kreeg ik de waarschuwing niet meer…


Antwoord 16

Ik heb deze waarschuwing opgelost door “Configuratiebeheer” te wijzigen in Vrijgeven (Mixed Plataform).


Antwoord 17

Ik kreeg deze waarschuwing in Visual Studio 2012 bij het compileren van een SQL Server 2012 SP1 SSIS-pijplijnscripttaak – totdat ik SQL Server 2012 SP2 installeerde.


Antwoord 18

Ik had hetzelfde probleem met het openen van de SQLite-verbinding, en het gebruik van de Nuget en het installeren van de component die in het project (SQLite) werd gebruikt, loste het op! probeer uw component op deze manier te installeren en controleer het resultaat


Antwoord 19

Ik wil alleen een bericht plaatsen voor degenen die de antwoorden hier niet vinden en hun probleem hebben opgelost.

Als u uw toepassing uitvoert, moet u ervoor zorgen dat de vervolgkeuzelijst voor het oplossingsplatform correct is ingesteld. de mijne was op x86, wat mij op zijn beurt dit probleem veroorzaakte.


Antwoord 20

Er zou een manier moeten zijn om een ​​.NET EXE/DLL AnyCPU te maken, en alle onbeheerde DLL’s waarvan het afhankelijk is, gecompileerd met zowel x86 als x64, beide gebundeld misschien met verschillende bestandsnamen en dan laadt de .NET-module dynamisch de juiste op basis van op de runtime-processorarchitectuur. Dat zou AnyCPU krachtig maken. Als de C++ DLL alleen x86 of x64 ondersteunt, is AnyCPU natuurlijk zinloos. Maar het idee van bundeling van beide dat ik nog moet zien geïmplementeerd omdat de configuratiemanager niet eens de mogelijkheid biedt om hetzelfde project twee keer te bouwen met een andere configuratie/platform voor meervoudige bundeling, waardoor AnyCPU of zelfs andere concepten zoals elke configuratie mogelijk zijn.

Other episodes