¿Cómo soluciono el error de compilación de Visual Studio, "desajuste entre la arquitectura del procesador"?

459

Soy nuevo en la configuración de proyectos en Visual Studio 2010, pero he investigado un poco y todavía no puedo resolver este problema. Tengo una solución de Visual Studio con una DLL de C ++ que hace referencia a la DLL de C #. La DLL de C # hace referencia a algunas otras DLL, algunas dentro de mi proyecto y otras externas. Cuando intento compilar la DLL de C ++, aparece esta advertencia:

advertencia MSB3270: Hubo una falta de coincidencia entre la arquitectura del procesador del proyecto que se está creando "MSIL" y la arquitectura del procesador de la referencia "[dll C # interno]", "x86".

Me dice que vaya al Administrador de configuración para alinear mis arquitecturas. La DLL de C # se configura con el objetivo de plataforma x86. Si trato de cambiar esto a otra cosa, como Any CPU, se queja porque una de las DLL externas de las que depende tiene el objetivo de plataforma x86.

Cuando miro Configuration Manager, muestra la Plataforma para mi C # DLL como x86 y para mi proyecto C ++ como Win32. Esta parece ser la configuración correcta; seguramente no quiero que el proyecto para mi proyecto C ++ tenga una plataforma establecida en x64, que es la única otra opción presentada.

¿Qué estoy haciendo mal aquí?

Paul Eastlund
fuente
¿Cuál es la queja, específicamente, cuando la cambia a Any CPU?
lordcheeto
2
No tengo suficiente información para hacer una sugerencia informada, pero haga clic con el botón derecho en su solución -> Orden de compilación del proyecto y asegúrese de que su proyecto C # se esté compilando antes del proyecto C ++. Si no es así, vaya a la pestaña Dependencias e infórmele a VS que el proyecto C ++ depende del proyecto C #.
lordcheeto
2
Visual Studio vuelve a ser una mierda en esto. La plataforma en la parte superior de mi pantalla dice x64 pero la advertencia dice que el proyecto que se está construyendo es "MSIL". Entonces Visual Studio me dice que hay una falta de coincidencia entre las manzanas y las naranjas cuando no estoy usando manzanas. ¿Podemos cambiarle el nombre a Visual Stupido?
Paul McCarthy
En lo que a mí respecta, este es un error en Visual Studio. Selecciono x64 como objetivo de plataforma y me dice que el proyecto se está construyendo para MSIL.
Paul McCarthy
La respuesta breve es que si su proyecto depende de x86 o x64, no puede usar Any CPU (que es solo para aplicaciones .NET puras). Por lo tanto, debe compilar para x64 o x32, no para cualquier CPU. Esto se deriva de la respuesta
zar

Respuestas:

513

Esta advertencia parece haberse introducido con el nuevo Visual Studio 11 Beta y .NET 4.5, aunque supongo que podría haber sido posible antes.

Primero, realmente es solo una advertencia. No debería doler nada si solo se trata de dependencias x86. Microsoft solo está tratando de advertirte cuando afirmas que tu proyecto es compatible con "Cualquier CPU" pero tienes una dependencia en un proyecto o ensamblado .dll que es x86 o x64. Debido a que tiene una dependencia x86, técnicamente su proyecto no es compatible con "Cualquier CPU". Para que la advertencia desaparezca, debe cambiar su proyecto de "Cualquier CPU" a "x86". Esto es muy fácil de hacer, aquí están los pasos.

  1. Vaya al elemento de menú Build | Configuration Manager.
  2. Encuentre su proyecto en la lista, en Plataforma, dirá "Cualquier CPU"
  3. Seleccione la opción "Cualquier CPU" del menú desplegable y luego seleccione <New..>
  4. Desde ese cuadro de diálogo, seleccione x86 en el menú desplegable "Nueva plataforma" y asegúrese de que "Cualquier CPU" esté seleccionado en el menú desplegable "Copiar configuración de".
  5. Presione OK
  6. Deberá seleccionar x86 para las configuraciones de Depuración y Liberación.

Esto hará que la advertencia desaparezca y también indicará que su ensamblaje o proyecto ya no es compatible con "Cualquier CPU" sino que ahora es específico para x86. Esto también es aplicable si está creando un proyecto de 64 bits que tiene una dependencia x64; simplemente seleccionarías x64 en su lugar.

Otra nota, los proyectos pueden ser compatibles con "Cualquier CPU", por lo general, si son proyectos .NET puros. Este problema solo aparece si introduce una dependencia (dll de terceros o su propio proyecto administrado C ++) que se dirige a una arquitectura de procesador específica.

David Sacks
fuente
3
Acabo de instalar el RTW de Visual Studio 2012 y abrí una solución 2010 preexistente y comencé a ver la misma advertencia, por lo que es algo que todavía existe en el RTW.
Tod Thomson
44
Dicho esto, creo que la respuesta de David es correcta, esta advertencia le permite saber que su aplicación realmente no es "AnyCPU", por lo que tendrá problemas cuando eventualmente la implemente en la arquitectura incorrecta.
Tod Thomson
66
Muy bien PUEDE doler algo. Un Any CPU exe se cargará como x64 en un sistema operativo de 64 bits y no podrá cargar x86 dlls. Entonces, si tiene una dependencia en una plataforma en particular, realmente debería configurar su plataforma correctamente.
Yaur
1
Parece que falta el menú Generar en VS C # 2010 Express. ¿Cómo llego a eso? Desearía que no ocultaran cosas.
Xonatron
1
Acabo de descubrir cómo habilitar el menú de compilación en Visual Studio 2010 Express: menú Herramientas -> Configuración -> seleccione 'Configuración experta'
Xonatron
144

Esta es una advertencia muy obstinada y, aunque es una advertencia válida, hay algunos casos en los que no se puede resolver debido al uso de componentes de terceros y otras razones. Tengo un problema similar, excepto que la advertencia se debe a que mi plataforma de proyectos es AnyCPU y estoy haciendo referencia a una biblioteca de MS creada para AMD64. Por cierto, esto está en Visual Studio 2010, y parece que se introdujo instalando VS2012 y .Net 4.5.

Como no puedo cambiar la biblioteca de MS a la que me refiero, y dado que sé que mi entorno de implementación de destino solo será de 64 bits, puedo ignorar este problema con seguridad.

¿Qué hay de la advertencia? Microsoft publicó en respuesta a un informe de Connect que una opción es deshabilitar esa advertencia. Solo debe hacer esto si conoce muy bien la arquitectura de su solución y comprende completamente su objetivo de implementación y sabe que en realidad no es un problema fuera del entorno de desarrollo.

Puede editar su archivo de proyecto y agregar este grupo de propiedades y configuración para deshabilitar la advertencia:

<PropertyGroup>
  <ResolveAssemblyWarnOrErrorOnTargetArchitectureMismatch>None</ResolveAssemblyWarnOrErrorOnTargetArchitectureMismatch>
</PropertyGroup>
Gio Palacino
fuente
1
La única otra referencia oficial de MS a esta solución que he visto está en el archivo Léame de Microsoft .NET Framework 4.5 RC . Extrañamente se eliminó del archivo Léame RTM.
JohnC
44
Esto funciona, pero no para una variación de la advertencia: "El ensamblaje al que se hace referencia ... apunta a un procesador diferente al de la aplicación". ¿Sería genial si hubiera una configuración similar para esta advertencia?
Jimmy
66
"Mi plataforma de proyectos es AnyCPU y estoy haciendo referencia a una biblioteca de MS creada para AMD64" ... Esto es INCORRECTO. Dado que su implementación de destino siempre es de 64 bits, puede configurar su plataforma en x64, lo que genera un error más apropiado si alguna vez se viola su suposición de 64 bits, y también evita la advertencia.
Ben Voigt
2
@BenVoigt es una gran idea en teoría, pero VS, al ser un proceso x86, necesita compilaciones de controles x86 para ejecutar cosas como el Diseñador de formularios de Windows, incluso si su aplicación solo será de 64 bits. Es una razón válida pero desafortunada para usar una compilación falsa de "Cualquier CPU".
jrh
1
@jrh: A continuación, poner la interfaz gráfica de usuario en un proyecto DLL, y la acumulación que como Cualquier CPU. El EXE debe marcarse con la arquitectura correcta para que coincida con las dependencias nativas. La separación adecuada de la GUI de la lógica es muy útil (aunque todavía tiene sus límites, como cuando el código nativo representa parte de la GUI, pero el soporte del diseñador es una causa perdida a menos que haga compilaciones de todo el proyecto para ambos x86 y x64)
Ben Voigt
61

Una buena regla general es "archivos DLL abiertos, archivos EXE cerrados", es decir:

  • EXE apunta al sistema operativo, especificando x86 o x64.
  • Las DLL se dejan abiertas (es decir, AnyCPU) para que puedan instanciarse dentro de un proceso de 32 bits o de 64 bits.

Cuando construye un EXE como AnyCPU, todo lo que está haciendo es diferir la decisión sobre qué bitness de proceso usar para el SO, lo que JITARÁ el EXE a su gusto. Es decir, un sistema operativo x64 creará un proceso de 64 bits, un sistema operativo x86 creará un proceso de 32 bits.

Crear DLL como AnyCPU los hace compatibles con cualquiera de los procesos.

Para obtener más información sobre las sutilezas de la carga del ensamblaje, consulte aquí . El resumen ejecutivo dice algo como:

  • AnyCPU : se carga como ensamblado x64 o x86, según el proceso de invocación
  • x86 : se carga como ensamblado x86; no se cargará desde un proceso x64
  • x64 : se carga como ensamblaje x64; no se cargará desde un proceso x86
Gustavo Mori
fuente
44
Esta regla tiene sentido para mí. Pero considere la siguiente situación: Native.dll (x64) usado por NetA.dll (Cualquier CPU) usado por NetB.dll (Cualquier CPU) usado por App1.exe (x64). No hay ningún problema real aquí, pero compilar NetA.dll me da la advertencia. Bien, dado que este ensamblado depende directamente de Native.dll, también podría marcarlo como x64. Pero luego compila NetB.dll se queja. Quiero mantener NetB.dll como "Cualquier CPU" porque es un ensamblado común utilizado en una aplicación diferente, de punto puro. Concluyo que mi única opción es suprimir / ignorar la advertencia. ¿Si?
Steve Robbins
2
Debido a la dependencia de Native.dll, su linaje completo de aplicación / ensamblaje ahora es x64, ya sea que suprima la advertencia o no. Si bien la supresión funciona en su escenario, podrían surgir situaciones extrañas en el futuro. Por ejemplo, 1) el ensamblaje NetB se usa en un entorno x86, donde Nativex64 no se cargará, o 2) su cliente quiere una versión x86 de App1.exe, y compila felizmente, ya que NetB está marcado como cualquier CPU, pero nuevamente, Nativex64 en la parte superior de la pila no se cargará
Gustavo Mori
Si bien la regla de Gustavo es un buen principio, no se puede usar para el problema específico que se hace en esta pregunta, ya que el proyecto ya depende de un ensamblado de terceros que no siguió la regla (es x86, no AnyCPU). Por lo tanto, mientras exista la dependencia, toda la cadena de proyectos debe apuntar a x86 y nada más.
David Burg
23

La DLL de C # se configura con el objetivo de plataforma x86

Este es el problema, una DLL realmente no puede elegir cuál será el bitness del proceso. Eso está completamente determinado por el proyecto EXE, ese es el primer ensamblaje que se carga, por lo que su configuración de objetivo de Plataforma es la que cuenta y establece la bitness para el proceso.

Las DLL no tienen otra opción, deben ser compatibles con el bitness del proceso. Si no lo son, obtendrá un gran Kaboom con una BadImageFormatException cuando su código intente usarlos.

Entonces, una buena selección para las DLL es AnyCPU para que funcionen de cualquier manera. Eso hace un montón de sentido para C # DLL, que hacen el trabajo de cualquier manera. Pero claro, no es su DLL de modo mixto C ++ / CLI, contiene código no administrado que solo puede funcionar bien cuando el proceso se ejecuta en modo de 32 bits. Usted puede obtener el sistema de construcción para generar advertencias acerca de eso. Que es exactamente lo que tienes. Solo advertencias, todavía se construye correctamente.

Solo soluciona el problema. Establezca el objetivo de la plataforma del proyecto EXE en x86, no funcionará con ninguna otra configuración. Y simplemente mantenga todos los proyectos de DLL en AnyCPU.

Hans Passant
fuente
1
Entonces, para ser claros: no estoy compilando el EXE, estoy construyendo una DLL para que se ejecute con el EXE de otra persona. Cambiar el objetivo de la plataforma de las DLL de C # a Cualquier CPU no elimina la advertencia. Me pregunto si este es un caso de connect.microsoft.com/VisualStudio/feedback/details/728901/… . Ignoraría la advertencia en sí, pero de hecho, el EXE puede cargar la DLL de C # pero no la DLL de C ++ Así que creo que este es un problema real.
Paul Eastlund
¿De hecho estás usando VS2010? Tampoco estaba claro en absoluto que no pudiera cargar la DLL de C ++ / CLI. ¿Qué es el diagnóstico? Actualice sus preguntas con esta información esencial.
Hans Passant
No había publicado sobre el fallo de la carga porque no estaba 100% seguro de que estuviera conectado, y en una mayor depuración resulta que no lo es. Estoy usando VS2010. Texto de pregunta actualizado. Perdón por la confusión
Paul Eastlund
1
No documentó ningún tipo de error o excepción relacionada con la carga de la DLL. No puedo ayudarte si no me dices lo que sabes. Suerte con ello.
Hans Passant
5

Estaba recibiendo la misma advertencia que hice esto:

  1. descargar proyecto
  2. editar propiedades del proyecto, es decir .csproj
  3. agregue la siguiente etiqueta:

    <PropertyGroup>
        <ResolveAssemblyWarnOrErrorOnTargetArchitectureMismatch>
            None
        </ResolveAssemblyWarnOrErrorOnTargetArchitectureMismatch>
    </PropertyGroup>
  4. Recargar el proyecto

yogeshwar gutte
fuente
2
Esto no está resolviendo el problema. Es solo deshabilitar la advertencia para el proyecto en particular. Pero en algunos casos me parece una solución válida. ¡Gracias!
Diminuto
4

Tuve este problema hoy y solo mirar las configuraciones de construcción en Visual Studio no estaba ayudando porque mostraba Any CPU tanto para el proyecto que no estaba construyendo como para el proyecto de referencia.

Luego busqué en el csproj del proyecto referenciado y encontré esto:

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

De alguna manera, este PlatformTarget se agregó en medio de un cambio de configuración y el IDE no pareció verlo.

Eliminar esta línea del proyecto al que se hace referencia resolvió mi problema.

JBourne
fuente
Me llevó un día entero resolver esto. ¡Muchas gracias! :)
SohamC
3

Si su DLL de C # tiene dependencias basadas en x86, entonces su propia DLL tendrá que ser x86. Realmente no veo una forma de evitar eso. VS se queja de cambiarlo a (por ejemplo) x64 porque un ejecutable de 64 bits no puede cargar bibliotecas de 32 bits.

Estoy un poco confundido acerca de la configuración del proyecto C ++. El mensaje de advertencia que se proporcionó para la compilación sugiere que estaba dirigido a AnyCPU, porque informó que la plataforma a la que apuntaba era [MSIL], pero usted indicó que la configuración para el proyecto era en realidad Win32. Una aplicación Win32 nativa no debería involucrar al MSIL, aunque probablemente necesitaría tener habilitado el soporte CLR si está interactuando con una biblioteca C #. Así que creo que hay algunas brechas en el lado de la información.

¿Puedo pedirle respetuosamente que revise y publique un poco más de detalle sobre la configuración exacta de los proyectos y cómo están relacionados entre sí? Se alegrará de ayudar más si es posible.

David W
fuente
3

Además de la respuesta David Sacks, es posible que tenga que ir a la Buildpestaña de la Project Propertiesy conjunto Platform Targetpara x86el proyecto que le está dando a estas advertencias. Aunque puede esperar que sea así, esta configuración no parece estar perfectamente sincronizada con la configuración en el administrador de configuración.

Dave Cousineau
fuente
2

Para proyectos de C #, el objetivo de x86 hace lo que parece. Dice que este ensamblaje solo admite arquitecturas x86. Del mismo modo para x64. Cualquier CPU, por otro lado, dice que no me importa qué arquitectura, soporto ambas. Entonces, las siguientes 2 preguntas son (1) ¿cuál es la configuración del ejecutable que usa estos dlls? y (2) cuál es el bitnessde su sistema operativo / computadora? La razón por la que pregunto es porque si su ejecutable está compilado para ejecutarse en 64 bits, entonces NECESITA todas las dependencias para poder ejecutarse también en modo de 64 bits. Su ensamblaje Any CPU debería poder cargarse, pero quizás hace referencia a alguna otra dependencia que solo es capaz de ejecutarse en la configuración x86. Verifique todas las dependencias y dependencias de dependencias para asegurarse de que todo sea "Cualquier CPU" o "x64" si planea ejecutar el ejecutable en modo de 64 bits. De lo contrario, tendrás problemas.

En muchos sentidos, Visual Studio no facilita la compilación de una mezcla de CPU y varios ensamblajes dependientes de la arquitectura. Es factible, pero a menudo requiere que un ensamblaje que de otro modo sería "Cualquier CPU" tenga que compilarse por separado para x86 y x64 porque alguna dependencia de alguna dependencia tiene dos versiones.

Jonathan DeCarlo
fuente
¿Es pertinente la configuración del ejecutable ya que tengo un error al intentar crear las DLL? (Sin embargo, es x86.) Mi computadora es x64.
Paul Eastlund
2
Es el ejecutable que determina qué bitness se utilizará. Si el ejecutable se ejecuta como x64, todo lo que cargue (directa o indirectamente) debe ser x64 o cualquier CPU. Si el ejecutable se ejecuta como x86, entonces todo lo que se carga (directa o indirectamente) debe ser x86 o cualquier CPU.
Jonathan DeCarlo
1

He tenido un problema similar antes, específicamente al agregar una solución de prueba a una solución x64 existente, como SharePoint. En mi caso, parece tener que ver con el hecho de que ciertas plantillas de proyecto se agregan como ciertas plataformas de forma predeterminada.

Aquí está la solución que a menudo funciona para mí: configure todo en la plataforma correcta en el Administrador de configuración (el menú desplegable de configuración activa, dice Debug normalmente, es una buena manera de llegar a él) y la plataforma del proyecto (en las propiedades del proyecto), luego compilar, luego vuelva a configurar todo en AnyCPU. A veces tengo que eliminar y volver a agregar algunas dependencias (DLL en las propiedades de cada proyecto) y, a veces, se debe cambiar la opción "Ejecutar pruebas en el proceso de 32 bits o de 64 bits" (hacer doble clic en Local.testsettings e ir a Hosts).

Me parece que esto es solo configurar algo y luego volver a configurarlo, pero probablemente haya más cosas detrás de escena que no estoy viendo. Sin embargo, funcionó de manera bastante consistente para mí en el pasado.

ssamuel
fuente
1

Para mi proyecto, tengo el requisito de poder compilar tanto en x86 como en x64. El problema con esto es que cada vez que agrega referencias mientras usa una, se queja cuando construye la otra.

Mi solución es editar manualmente los archivos * .csproj para que líneas como estas:

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

cambiarse a esto:

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

Tuve un problema similar que fue causado por MS UNIT Test DLL. Mi aplicación WPF se compiló como x86 pero la unidad de prueba DLL (archivo EXE referenciado) como "Cualquier CPU". Cambié la DLL de prueba unitaria para que se compilara para x86 (igual que EXE) y se volvió a publicar.

usuario1257110
fuente
0

Debería haber una manera de hacer un .NET EXE / DLL AnyCPU, y cualquier DLL no administrado del que dependa compilada tanto con x86 como con x64, ambas agrupadas quizás con diferentes nombres de archivo y luego el módulo .NET cargando dinámicamente el correcto en función de su tiempo de ejecución arquitectura del procesador Eso haría que AnyCPU sea poderoso. Si la DLL de C ++ solo admite x86 o x64, AnyCPU, por supuesto, no tiene sentido. Pero la idea de la agrupación que todavía tengo que ver implementada, ya que el administrador de configuración ni siquiera proporciona un medio para construir el mismo proyecto dos veces con una configuración / plataforma diferente para la agrupación múltiple, permitiendo que AnyCPU o incluso otros conceptos como cualquier configuración sea posible.

Gregory Morse
fuente
2
bienvenido a stackoverflow! ¿Puedes intentar enfocar / reformatear esta respuesta un poco?
Corley Brigman
Parece que sería una buena pregunta, una publicación de blog o una solicitud de función en Connect ... en realidad no responde a esta.
Ben Voigt
0

Tuve una advertencia muy similar en mi construcción. Mis proyectos se configuraron para apuntar a .NET 4.5, en el servidor de compilación se instaló el SDK de Windows 8.1 (para .NET 4.5.1). Después de actualizar mis proyectos para apuntar a .NET 4.5.1 (no fue un problema para mí, fue para una aplicación completamente nueva), ya no recibí la advertencia ...

NicoCV
fuente
0

Resolví esta advertencia cambiando "Configuration Manager" a Release (Mixed Plateform).

Edu Pelais
fuente
0

Recibí esta advertencia en Visual Studio 2012 al compilar una tarea de secuencia de comandos de canalización SSIS de SQL Server 2012 SP1, hasta que instalé SQL Server 2012 SP2.

cdonner
fuente
0

¡Tuve el mismo problema con la conexión de apertura de SQLite, y al usar Nuget e instalar el componente utilizado en el proyecto (SQLite) lo solucioné! intente instalar su componente de esta manera y verifique el resultado

StudioX
fuente