Come posso correggere l'errore di compilazione di Visual Studio, "mancata corrispondenza tra architettura del processore"?


459

Sono nuovo a progettare la configurazione in Visual Studio 2010, ma ho fatto alcune ricerche e non riesco ancora a capire questo problema. Ho una soluzione di Visual Studio con una DLL C ++ che fa riferimento alla DLL C #. La DLL C # fa riferimento ad alcune altre DLL, alcune all'interno del mio progetto e altre esterne. Quando provo a compilare la DLL C ++, ricevo questo avviso:

avviso MSB3270: si è verificata una discrepanza tra l'architettura del processore del progetto in fase di creazione "MSIL" e l'architettura del processore del riferimento "[dll C # interno]", "x86".

Mi dice di andare a Configuration Manager per allineare le mie architetture. La DLL C # è impostata con la piattaforma target x86. Se provo a cambiarlo in qualcos'altro, come Qualsiasi CPU, si lamenta perché una delle DLL esterne da cui dipende ha la piattaforma x86 di destinazione.

Quando guardo Configuration Manager mostra la piattaforma per la mia DLL C # come x86 e per il mio progetto C ++ come Win32. Sembra la giusta installazione; sicuramente non voglio che il progetto per il mio progetto C ++ abbia la piattaforma impostata su x64, che è l'unica altra opzione presentata.

Cosa sto facendo di sbagliato qui?


Qual è il reclamo, in particolare, quando lo cambi in Qualsiasi CPU?
lordcheeto,

2
Non ho abbastanza informazioni per dare un suggerimento informato, ma fai clic con il pulsante destro del mouse sulla tua soluzione -> Ordine di costruzione del progetto e assicurati che il tuo progetto C # venga creato prima del progetto C ++. In caso contrario, vai alla scheda Dipendenze e fai sapere a VS che il progetto C ++ dipende dal progetto C #.
lordcheeto,

2
Visual Studio è di nuovo una schifezza. La piattaforma nella parte superiore del mio schermo dice x64 ma l'avviso dice che il progetto in costruzione è "MSIL". Visual Studio mi sta dicendo che c'è una discrepanza tra mele e arance quando non sto usando le mele. Possiamo rinominarlo in Visual Stupido?
Paul McCarthy,

Per quanto mi riguarda, questo è un bug in Visual Studio. Seleziono x64 come destinazione della piattaforma e mi dice che il progetto è stato creato per MSIL.
Paul McCarthy,

La risposta breve è se il tuo progetto ha dipendenze da x86 o x64, non puoi usare qualsiasi CPU (che è solo per le applicazioni .NET pure). Quindi devi costruire per x64 o x32, non per qualsiasi CPU. Questo deriva dalla risposta
zar

Risposte:


513

Questo avviso sembra essere stato introdotto con il nuovo Visual Studio 11 Beta e .NET 4.5, anche se suppongo che sarebbe stato possibile prima.

Innanzitutto, è davvero solo un avvertimento. Non dovrebbe danneggiare nulla se hai a che fare con dipendenze x86. Microsoft sta solo cercando di avvisarti quando dichiari che il tuo progetto è compatibile con "Any CPU" ma hai una dipendenza da un progetto o da un assembly DLL che è x86 o x64. Poiché hai una dipendenza x86, tecnicamente il tuo progetto non è quindi compatibile con "Qualsiasi CPU". Per far sparire l'avvertimento, dovresti effettivamente cambiare il tuo progetto da "Qualsiasi CPU" a "x86". È molto facile da fare, ecco i passaggi.

  1. Vai alla voce di menu Build | Configuration Manager.
  2. Trova il tuo progetto nell'elenco, sotto Piattaforma verrà visualizzato "Qualsiasi CPU"
  3. Seleziona l'opzione "Qualsiasi CPU" dal menu a discesa, quindi seleziona <New..>
  4. Da quella finestra di dialogo, selezionare x86 dal menu a discesa "Nuova piattaforma" e assicurarsi che "Qualsiasi CPU" sia selezionato nel menu a discesa "Copia impostazioni da".
  5. Premi OK
  6. Dovrai selezionare x86 per entrambe le configurazioni Debug e Release.

Questo farà scomparire l'avvertimento e affermerà anche che l'assembly o il progetto non sono più compatibili con "Qualsiasi CPU" ma ora specifici per x86. Questo è applicabile anche se stai costruendo un progetto a 64 bit che ha una dipendenza x64; dovresti semplicemente selezionare x64 invece.

Un'altra nota, i progetti possono essere compatibili con "Qualsiasi CPU" di solito se sono progetti .NET puri. Questo problema si presenta solo se si introduce una dipendenza (dll di terze parti o il proprio progetto gestito C ++) destinato a un'architettura di processore specifica.


3
Ho appena installato RTW di Visual Studio 2012 e ho aperto una soluzione preesistente 2010 e ho iniziato a vedere lo stesso avviso, quindi è qualcosa che esiste ancora in RTW.
Tod Thomson,

4
Detto questo, penso che la risposta di David sia corretta, questo avvertimento ti sta facendo sapere che la tua app non è davvero "AnyCPU", quindi ti imbatterai in problemi quando alla fine la distribuirai nell'architettura sbagliata.
Tod Thomson,

6
Molto bene PU hurt fare del male a qualcosa. Un exe Any CPU verrà caricato come x64 su un sistema operativo a 64 bit e non sarà in grado di caricare dll x86. Quindi, se hai una dipendenza da una particolare piattaforma, dovresti davvero impostare correttamente la tua piattaforma.
Yaur,

1
Il menu Build sembra mancare in VS C # 2010 Express. Come ci arrivo? Vorrei che non nascondessero le cose.
Xonatron,

1
Ho appena scoperto come abilitare il menu di creazione in Visual Studio 2010 Express: menu Strumenti -> Impostazioni -> seleziona "Impostazioni
avanzate

144

Questo è un avvertimento molto testardo e mentre è un avvertimento valido ci sono alcuni casi in cui non può essere risolto a causa dell'uso di componenti di terze parti e altri motivi. Ho un problema simile, tranne per il fatto che l'avviso è dovuto al fatto che la mia piattaforma di progetti è AnyCPU e mi riferisco a una libreria MS creata per AMD64. Questo è in Visual Studio 2010 tra l'altro, e sembra essere stato introdotto installando VS2012 e .Net 4.5.

Dal momento che non riesco a modificare la libreria MS a cui faccio riferimento e poiché so che il mio ambiente di distribuzione di destinazione sarà sempre e solo a 64 bit, posso tranquillamente ignorare questo problema.

Che dire dell'avvertimento? Microsoft ha pubblicato in risposta a un rapporto Connect che un'opzione è disabilitare tale avviso. Dovresti farlo solo se sei molto consapevole dell'architettura della tua soluzione e capisci perfettamente il tuo obiettivo di distribuzione e sai che non è davvero un problema al di fuori dell'ambiente di sviluppo.

È possibile modificare il file di progetto e aggiungere questo gruppo di proprietà e le impostazioni per disabilitare l'avviso:

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

1
L'unico altro riferimento MS ufficiale a questa soluzione che ho visto è nel file Leggimi RC di Microsoft .NET Framework 4.5 . Stranamente è stato rimosso dal file Leggimi RTM.
Giovanni

4
Funziona, ma non per una variazione dell'avvertimento: "L'assembly di riferimento ... ha come target un processore diverso dall'applicazione". Sarebbe bello se ci fosse un'impostazione simile per questo avviso?
Jimmy,

6
"La mia piattaforma di progetti è AnyCPU e sto facendo riferimento a una libreria MS creata per AMD64" ... Questo è SBAGLIATO. Poiché la distribuzione di destinazione è sempre a 64 bit, è possibile impostare la piattaforma su x64, il che rende un errore più appropriato se il presupposto a 64 bit viene mai violato e impedisce anche l'avviso.
Ben Voigt,

2
@BenVoigt in teoria è una grande idea, ma essendo VS un processo x86 richiede build x86 di controlli per eseguire cose come Progettazione Windows Form, anche se l'applicazione sarà sempre a 64 bit. È un motivo valido, ma sfortunato, per usare una build "Any CPU" falsa.
1818

1
@jrh: Poi mettere l'interfaccia grafica in un progetto DLL e accumulo che come AnyCPU. EXE deve essere contrassegnato con l'architettura corretta per abbinare le dipendenze native. La corretta separazione della GUI dalla logica fa molta strada (anche se ha ancora i suoi limiti, come quando il codice nativo rende parte della GUI, ma il supporto del progettista è una causa persa a meno che non si realizzi build dell'intero progetto per entrambi x86 e x64)
Ben Voigt,

61

Una buona regola empirica è "DLL aperte, EXE chiusi", ovvero:

  • EXE prende di mira il sistema operativo, specificando x86 o x64.
  • Le DLL vengono lasciate aperte (ad es. AnyCPU) in modo da poter essere istanziate all'interno di un processo a 32 o 64 bit.

Quando si crea un EXE come AnyCPU, tutto ciò che si sta facendo è rinviare la decisione su quale processo Bitness utilizzare per il sistema operativo, che JIT verrà eseguito a suo piacimento. Cioè, un sistema operativo x64 creerà un processo a 64 bit, un sistema operativo x86 creerà un processo a 32 bit.

La creazione di DLL come AnyCPU li rende compatibili con entrambi i processi.

Per ulteriori informazioni sulle sottigliezze del caricamento degli assiemi, vedere qui . Il sommario esecutivo recita qualcosa del tipo:

  • AnyCPU : carica come assembly x64 o x86, a seconda del processo di invocazione
  • x86 - carica come assembly x86; non verrà caricato da un processo x64
  • x64 - carica come assembly x64; non verrà caricato da un processo x86

4
Questa regola ha senso per me. Tuttavia, considerare la seguente situazione: Native.dll (x64) utilizzato da NetA.dll (qualsiasi CPU) utilizzato da NetB.dll (qualsiasi CPU) utilizzato da App1.exe (x64). Non ci sono problemi reali qui, ma la compilazione di NetA.dll mi dà l'avvertimento. OK, poiché questo assembly dipende direttamente da Native.dll, potrei contrassegnarlo anche come x64. Ma poi compila NetB.dll si lamenta. Voglio mantenere NetB.dll come "Qualsiasi CPU" perché è un assembly comune utilizzato in un'applicazione diversa, pure-dot-net. Concludo che la mia unica opzione è quella di sopprimere / ignorare l'avvertimento. Sì?
Steve Robbins,

2
A causa della dipendenza da Native.dll, l'intera discendenza app / assembly ora è x64, indipendentemente dal fatto che venga soppresso l'avviso o meno. Mentre la soppressione funziona nel tuo scenario, potrebbero sorgere strane situazioni in futuro. Ad esempio, 1) l'assemblaggio di NetB viene utilizzato in un ambiente x86, in cui Nativex64 non viene caricato, oppure 2) il cliente desidera una versione x86 di App1.exe e la compilazione felice, poiché NetB è contrassegnato come qualsiasi CPU, ma di nuovo, Nativex64 nella parte superiore della pila non verrà caricato
Gustavo Mori il

Sebbene la regola di Gustavo sia un buon principio, non può essere utilizzata per il problema specifico posto in questa domanda poiché il progetto ha già una dipendenza da un assembly di terze parti che non ha seguito la regola (è x86, non AnyCPU). Quindi, finché esiste la dipendenza, l'intera catena di progetti deve essere indirizzata a x86 e nient'altro.
David Burg,

23

La DLL C # è impostata con la piattaforma target x86

Qual è il tipo di problema, una DLL in realtà non riesce a scegliere quale sarà il testimone del processo. Questo è interamente determinato dal progetto EXE, è il primo assembly che viene caricato, quindi l'impostazione di destinazione della piattaforma è quella che conta e imposta il testimone per il processo.

Le DLL non hanno scelta, devono essere compatibili con il testimone del processo. In caso contrario, otterrai un grosso Kaboom con BadImageFormatException quando il tuo codice tenta di usarli.

Quindi una buona selezione per le DLL è AnyCPU, quindi funzionano in entrambi i modi. Che fa un sacco di senso per C # DLL, che fanno il lavoro in entrambi i modi. Ma certo, non la tua DLL in modalità mista C ++ / CLI, contiene codice non gestito che può funzionare bene solo quando il processo viene eseguito in modalità a 32 bit. È possibile ottenere il sistema di generazione per generare avvisi a tale proposito. È esattamente quello che hai. Solo avvertimenti, si costruisce ancora correttamente.

Basta punt il problema. Imposta il target della piattaforma del progetto EXE su x86, non funzionerà con nessun'altra impostazione. E mantieni tutti i progetti DLL su AnyCPU.


1
Quindi, per essere chiari: non sto costruendo il file EXE, sto costruendo una DLL da eseguire con il file EXE di qualcun altro. La modifica della destinazione della piattaforma delle DLL C # su Qualsiasi CPU non elimina l'avviso. Mi chiedo se questo è un caso di connect.microsoft.com/VisualStudio/feedback/details/728901/… - Vorrei ignorare l'avvertimento stesso, ma in effetti il ​​EXE è in grado di caricare la DLL C # ma non la DLL C ++ quindi penso che questo sia un vero problema.
Paul Eastlund,

Stai effettivamente utilizzando VS2010? Inoltre non era affatto chiaro che non si potesse caricare la DLL C ++ / CLI. Qual è la diagnostica? Aggiorna le tue domande con queste informazioni essenziali.
Hans Passant,

Non avevo postato sull'errore di caricamento perché non ero sicuro al 100% che fosse collegato, e su un ulteriore debug risulta che non lo è. Sto usando VS2010. Testo della domanda aggiornato. Molto dispiaciuto per la confusione
Paul Eastlund,

1
Non hai documentato alcun tipo di errore o eccezione relativa al caricamento della DLL. Non posso aiutarti se non mi dici quello che sai. Buona fortuna.
Hans Passant,

5

Stavo ricevendo lo stesso avvertimento che ho fatto questo:

  1. scarica il progetto
  2. modificare le proprietà del progetto, ad esempio .csproj
  3. aggiungi il seguente tag:

    <PropertyGroup>
        <ResolveAssemblyWarnOrErrorOnTargetArchitectureMismatch>
            None
        </ResolveAssemblyWarnOrErrorOnTargetArchitectureMismatch>
    </PropertyGroup>
  4. Ricarica il progetto


2
Questo non risolve il problema. Sta solo disabilitando l'avvertimento per quel particolare progetto. Ma in alcuni casi la trovo una soluzione valida. Grazie!
Piccolo

4

Ho avuto questo problema oggi e solo guardare le configurazioni degli edifici in Visual Studio non mi ha aiutato perché mostrava Qualsiasi CPU sia per il progetto che non stava costruendo sia per il progetto di riferimento.

Ho quindi cercato nel csproj del progetto di riferimento e ho trovato questo:

<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>

In qualche modo questo PlatformTarget è stato aggiunto nel mezzo di una modifica della configurazione e l'IDE non sembrava vederlo.

La rimozione di questa riga dal progetto di riferimento ha risolto il mio problema.


Mi ci è voluto un giorno intero per capirlo. Molte grazie! :)
SohamC

3

Se la tua DLL C # ha dipendenze basate su x86, allora la tua stessa DLL dovrà essere x86. Non vedo davvero un modo per aggirare questo. VS si lamenta di averlo cambiato in (ad esempio) x64 perché un eseguibile a 64 bit non può caricare librerie a 32 bit.

Sono un po 'confuso sulla configurazione del progetto C ++. Il messaggio di avviso fornito per la build suggerisce che è stato scelto come target per AnyCPU, in quanto ha segnalato che la piattaforma di destinazione era [MSIL], ma hai indicato che la configurazione per il progetto era effettivamente Win32. Un'app Win32 nativa non dovrebbe coinvolgere MSIL, anche se probabilmente avrebbe bisogno del supporto CLR abilitato se interagisce con una libreria C #. Quindi penso che ci siano alcune lacune sul lato delle informazioni.

Posso rispettosamente chiederti di rivedere e pubblicare un po 'più di dettaglio sull'esatta configurazione dei progetti e su come sono correlati? Sii felice di aiutare ulteriormente se possibile.


3

Oltre alla risposta di David Sacks, potresti anche dover accedere alla Buildscheda di Project Propertiese impostare Platform Targetsu x86per il progetto che ti sta dando questi avvisi. Sebbene ci si possa aspettare che sia, questa impostazione non sembra essere perfettamente sincronizzata con l'impostazione nel Configuration Manager.


2

Per i progetti C #, l'obiettivo di x86 fa quello che sembra. Dice che questo assembly supporta solo architetture x86. Allo stesso modo per x64. Qualsiasi CPU d'altra parte dice che non mi interessa quale architettura, io sostengo entrambi. Quindi, le prossime 2 domande sono (1) qual è la configurazione dell'eseguibile che usa queste dll? e (2) qual è il testimonedel tuo sistema operativo / computer? Il motivo per cui ti chiedo è perché se il tuo eseguibile è compilato per funzionare in 64-bit, allora HA BISOGNO di tutte le dipendenze per poter funzionare anche in modalità 64-bit. Il tuo gruppo Any CPU dovrebbe essere in grado di essere caricato, ma forse fa riferimento a qualche altra dipendenza che può essere eseguita solo nella configurazione x86. Controlla tutte le dipendenze e le dipendenze delle dipendenze per assicurarti che tutto sia "Any CPU" o "x64" se prevedi di eseguire l'eseguibile in modalità 64-bit. Altrimenti, avrai problemi.

In molti modi, Visual Studio non semplifica la compilazione di una combinazione di qualsiasi CPU e vari assiemi dipendenti dall'architettura. È fattibile, ma spesso richiede che un assembly che altrimenti sarebbe "Qualsiasi CPU" debba essere compilato separatamente per x86 e x64 perché alcune dipendenze di una dipendenza da qualche parte hanno due versioni.


La configurazione della materia eseguibile è pertinente poiché sto riscontrando un errore solo nel tentativo di creare le DLL? (È x86 però.) Il mio computer è x64.
Paul Eastlund,

2
È l'eseguibile che determina quale testimone verrà utilizzato. Se l'eseguibile è in esecuzione come x64, tutto ciò che carica (direttamente o indirettamente) deve essere x64 o qualsiasi CPU. Se l'eseguibile è in esecuzione come x86, qualsiasi cosa sia caricata (direttamente o indirettamente) deve essere x86 o qualsiasi CPU.
Jonathan DeCarlo,

1

Ho avuto un problema simile prima, in particolare quando ho aggiunto una soluzione di prova a una soluzione x64 esistente, come SharePoint. Nel mio caso, sembra avere a che fare con il fatto che determinati modelli di progetto vengono aggiunti come determinate piattaforme per impostazione predefinita.

Ecco la soluzione che spesso funziona per me: imposta tutto sulla piattaforma corretta in Configuration Manager (il menu a discesa della configurazione attiva, dice Debug normalmente, è un buon modo per arrivarci) e la piattaforma di progetto (nelle proprietà del progetto), quindi compilare, quindi reimpostare tutto su AnyCPU. A volte devo rimuovere e aggiungere nuovamente alcune dipendenze (DLL nelle proprietà di ciascun progetto) e talvolta "Esegui test nel processo a 32 bit o 64 bit" (fai doppio clic su Local.testsettings e vai a Host) deve essere modificato.

Mi sembra che si tratti solo di impostare qualcosa e poi di ripristinarlo, ma probabilmente c'è qualcosa in più dietro le quinte che non vedo. In passato ha funzionato abbastanza coerentemente per me.


1

Per il mio progetto, ho un requisito per essere in grado di costruire sia su x86 che x64. Il problema è che ogni volta che aggiungi riferimenti mentre ne usi uno, allora si lamenta quando costruisci l'altro.

La mia soluzione è modificare manualmente i file * .csproj in modo che linee come queste:

<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"/>

essere cambiato in questo:

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

1

Ho avuto un problema simile a quello causato da MS UNIT Test DLL. La mia applicazione WPF è stata compilata come x86 ma DLL test unità (file EXE di riferimento) come "Qualsiasi CPU". Ho cambiato la DLL di unit test per essere compilata per x86 (uguale a EXE) ed è stata rimossa.



0

Dovrebbe esserci un modo per creare un AnyCPU .NET / DLL EXE e qualsiasi DLL non gestita da cui dipende sia compilata con x86 che x64, entrambe in bundle forse con nomi di file diversi e quindi il modulo .NET carica dinamicamente quello corretto in base al suo runtime architettura del processore. Ciò renderebbe AnyCPU potente. Se la DLL C ++ supporta solo x86 o x64, AnyCPU è ovviamente inutile. Ma il bundling di entrambe le idee che devo ancora vedere implementate come gestore della configurazione non fornisce nemmeno un mezzo per costruire lo stesso progetto due volte con una diversa configurazione / piattaforma per il raggruppamento multiplo, consentendo AnyCPU o anche altri concetti come qualsiasi configurazione.


2
benvenuto in StackOverflow! puoi provare a focalizzare / riformattare un po 'questa risposta?
Corley Brigman,

Sembra che sarebbe una buona domanda, o un post sul blog o una richiesta di funzionalità su Connect ... in realtà non risponde a questa.
Ben Voigt,

0

Ho avuto un avviso molto simile nella mia build. I miei progetti erano impostati su .NET 4.5, sul server di build è stato installato l'SDK di Windows 8.1 (per .NET 4.5.1). Dopo aver aggiornato i miei progetti su .NET 4.5.1 (non era un problema per me, era per un'applicazione completamente nuova), non ho più ricevuto l'avviso ...


0

Ho risolto questo avviso cambiando "Configuration Manager" in Release (Mixed Plataform).


0

Ho ricevuto questo avviso in Visual Studio 2012 durante la compilazione di un'attività di script della pipeline SSIS di SQL Server 2012 SP1, fino all'installazione di SQL Server 2012 SP2.


0

Ho avuto lo stesso problema con l'apertura della connessione SQLite e l'utilizzo del Nuget e l'installazione del componente utilizzato nel progetto (SQLite) lo hanno risolto! prova a installare il componente in questo modo e controlla il risultato


Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.