2012-04-11 43 views
352

Soy nuevo en la configuración del proyecto en Visual Studio 2010, pero he hecho algo de research 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 el C++ DLL, consigo esta advertencia:¿Cómo soluciono el error de compilación de Visual Studio, "falta de coincidencia entre la arquitectura del procesador"?

advertencia MSB3270: Hubo una falta de correspondencia entre la arquitectura del procesador del proyecto es construir "MSIL" y la arquitectura del procesador de la referencia "[interno C# dll] "," x86 ".

Me dice que vaya a Configuration Manager para alinear mis arquitecturas. La DLL C# está configurada con la plataforma objetivo x86. Si trato de cambiar esto a otra cosa, como Cualquier CPU, se queja porque una de las DLL externas es depende de que tenga la plataforma objetivo x86.

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

¿Qué estoy haciendo mal aquí?

+0

¿Cuál es la queja, específicamente, cuando la cambia a Cualquier CPU? – lordcheeto

+2

No tengo suficiente información para hacer una sugerencia informada, pero haga clic derecho en su solución -> Orden de compilación del proyecto y asegúrese de que su proyecto C# se está construyendo antes del proyecto C++. Si no es así, vaya a la pestaña Dependencias y permita que VS sepa que el proyecto C++ depende del proyecto C#. – lordcheeto

+1

Paul, ¿regresarías y aceptarías una respuesta? Creo que esta es una gran pregunta para mucha gente y tienes una muy buena respuesta de David. –

Respuesta

401

Parece que esta advertencia se introdujo con el nuevo Visual Studio 11 Beta y .NET 4.5, aunque supongo que podría haber sido posible antes.

En primer lugar, es solo una advertencia. No debería doler nada si solo está lidiando con dependencias x86. Microsoft solo intenta advertirle cuando afirma que su proyecto es compatible con "Cualquier CPU" pero tiene una dependencia en un proyecto o ensamblado .dll que sea x86 o x64. Como tiene una dependencia x86, técnicamente su proyecto no es compatible con "Any CPU". Para que la advertencia desaparezca, en realidad 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 del menú Build | Configuration Manager.
  2. Encuentra su proyecto en la lista, en la plataforma dirá "Cualquier CPU"
  3. seleccionar la opción "Cualquier CPU" en el menú desplegable y luego seleccione <New..>
  4. A partir de ese diálogo, seleccione X 86 de la "Nueva Platform "desplegable y asegúrese de que" Any CPU "esté seleccionado en la lista desplegable" Copy settings from ".
  5. Marque OK
  6. Deseará 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 de x86. Esto también es aplicable si está construyendo un proyecto de 64 bits que tiene una dependencia x64; usted simplemente seleccionaría 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 en C++) que se dirige a una arquitectura de procesador específica.

+3

Acabo de instalar el RTW de Visual Studio 2012 y abrí una solución preexistente de 2010 y empecé a ver la misma advertencia, por lo que es algo que todavía existe en el RTW. –

+3

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 se encontrará con problemas cuando finalmente la implemente en la arquitectura incorrecta. –

+5

Está 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 particular, realmente debería configurar su plataforma correctamente. – Yaur

2

Para proyectos 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, apoyo ambas. Entonces, las próximas 2 preguntas son (1) ¿cuál es la configuración del ejecutable que usa estos dlls? y (2) ¿cuál es el bitness de 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 funcionar también en el modo de 64 bits. Su ensamblado Any CPU debe poder cargarse, pero quizás esté haciendo referencia a alguna otra dependencia que solo pueda ejecutarse en la configuración x86. Compruebe 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.

De muchas formas, Visual Studio no hace que la compilación sea una mezcla de Any CPU y varios ensambles dependientes de la arquitectura. Es factible, pero a menudo requiere que un ensamblaje que de otro modo sería "Cualquier CPU" tenga que ser compilado por separado para x86 y x64 porque alguna dependencia de dependencia en alguna parte tiene dos versiones.

+0

¿La configuración del archivo ejecutable es pertinente ya que estoy obteniendo un error solo al tratar de compilar los archivos DLL? (Sin embargo, es x86.) Mi computadora es x64. –

+2

Es el ejecutable el que determina qué * bitness * se usará. 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, todo lo que se carga (directa o indirectamente) debe ser x86 o cualquier CPU. –

21

El C# DLL está configurado con x86 plataforma de destino

que es un poco el problema, una DLL en realidad no llega a elegir cuál será el valor de bits 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 destino de plataforma es la que cuenta y establece el bitness para el proceso.

Las DLL no tienen otra opción, deben ser compatibles con la bitness del proceso. Si no lo están, obtendrás un gran Kaboom con BadImageFormatException cuando tu código intente usarlos.

Así que una buena selección para las DLL es AnyCPU por lo que funcionan de cualquier manera. Eso tiene mucho sentido para C# DLLs, ellos do funcionan de cualquier manera. Pero seguro, 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 compilación para generar advertencias al respecto.Que es exactamente lo que tienes. Solo advertencias, todavía se construye correctamente.

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

+1

Entonces, para ser claros: no estoy construyendo el EXE, estoy construyendo un archivo DLL para que se ejecute con el EXE de otra persona. Cambiar el destino de la plataforma de las DLL de C# a cualquier CPU no elimina la advertencia. Me pregunto si este es un caso de http://connect.microsoft.com/VisualStudio/feedback/details/728901/msb3270-bogus-warning-with-c-mixed-project - Yo ignoraría la advertencia en sí, pero de hecho, el EXE puede cargar el DLL de C# pero no el DLL de C++, así que creo que este es un problema real. –

+0

¿De hecho está usando VS2010? Tampoco estaba claro en absoluto que no pudiera cargar la DLL C++/CLI. ¿Cuál es el diagnóstico? Actualiza tus preguntas con esta información esencial. –

+0

No se ha publicado sobre la falla de carga porque no estaba 100% seguro de que estaba conectado, y en la depuración posterior no resulta ser. Estoy usando VS2010. Texto de pregunta actualizado Lo siento mucho por la confusión –

1

Si su C# DLL tiene dependencias basadas en x86, entonces su DLL en sí 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 fue apuntado para AnyCPU, porque informó que la plataforma a la que apuntaba era [MSIL], pero indicó que la configuración para el proyecto era en realidad Win32. Una aplicación Win32 nativa no debería involucrar al MSIL, aunque es probable que necesite tener el soporte CLR habilitado si está interactuando con una biblioteca C#. Entonces creo que hay algunas lagunas en el lado de la información.

¿Podría respetuosamente pedirle que revise y publique un poco más de detalle de la configuración exacta de los proyectos y cómo se relacionan entre sí? Esté contento de ayudar aún más si es posible.

111

Esta es una advertencia muy obstinada y si bien 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. Esto está en Visual Studio 2010 por cierto, y parece ser introducido mediante la instalación de VS2012 y .Net 4.5.

Como no puedo cambiar la biblioteca de MS a la que me refiero, y como sé que mi entorno de despliegue de destino solo será de 64 bits, puedo ignorar este problema de forma segura.

¿Qué pasa con la advertencia? Microsoft publicó en respuesta al a Connect report que una opción es desactivar esa advertencia. Solo debe hacer esto. Es muy consciente de la arquitectura de su solución y comprende completamente su objetivo de despliegue y sabe que no es realmente un problema fuera del entorno de desarrollo.

Aquí puede editar su archivo de proyecto y agregar este grupo de propiedades y el establecimiento de desactivar la advertencia:

<PropertyGroup> 
    <ResolveAssemblyWarnOrErrorOnTargetArchitectureMismatch>None</ResolveAssemblyWarnOrErrorOnTargetArchitectureMismatch> 
</PropertyGroup> 
+0

La única otra referencia oficial de MS a esta solución que he visto se encuentra en el archivo [Microsoft .NET Framework 4.5 RC Readme] (http://download.microsoft.com/download/2/8/B/28BB331C-7F39 -4869-BA77-90452D24BB96/Net% 20Framework% 204.5% 20RC% 20Readme_enu.htm). Extrañamente, se eliminó del archivo Readme de RTM. – JohnC

+4

Esto funciona, pero no para una variación de la advertencia: "El ensamblaje al que se hace referencia ... se dirige a un procesador diferente de la aplicación". Sería genial si hubiera una configuración similar para esta advertencia? – Jimmy

+2

"mi plataforma de proyectos es AnyCPU y estoy haciendo referencia a una biblioteca 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 lo convierte en un error más apropiado si su supuesto de 64 bits se viola alguna vez, y también evita la advertencia. –

1

He tenido un problema similar antes, específicamente cuando se añade 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 proyectos se agregan como ciertas plataformas por defecto.

Aquí está la solución que a menudo me funciona: configure todo en la plataforma correcta en Configuration Manager (el menú desplegable de configuración activa, dice Debug normalmente, es una buena forma de llegar a él) y la plataforma del proyecto (en proyecto propiedades), luego construye, luego configura todo de vuelta a AnyCPU. A veces tengo que eliminar y volver a agregar algunas dependencias (archivos DLL en las propiedades de cada proyecto) y, a veces, se debe modificar "Ejecutar pruebas en un proceso de 32 bits o de 64 bits" (hacer doble clic en Local.testsettings e ir a Hosts).

Me parece que esto es solo establecer 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.

50

Una buena regla de oro es "DLL abiertos, cerrados EXE", es decir:

  • EXE objetivos del sistema operativo, especificando x86 o x64.
  • Las DLL se dejan abiertas (es decir, AnyCPU) por lo que se pueden crear instancias dentro de un proceso de 32 bits o de 64 bits.

Cuando construye un EXE como AnyCPU, todo lo que hace es posponer la decisión sobre qué bitness de proceso usar para el sistema operativo, lo que JIT el EXE le agradará. Es decir, un sistema operativo x64 creará un proceso de 64 bits, un sistema operativo x86 creará un proceso de 32 bits.

La construcción de archivos DLL como AnyCPU los hace compatibles con cualquier proceso.

Para obtener más información sobre las sutilezas de la carga de montaje, consulte here. El resumen dice algo así como:

  • Cualquier CPU - cargas como x64 o x86 de montaje, dependiendo del proceso de invocación
  • x 86 - cargas como ensamblador x86; no se cargará desde un proceso x64
  • x64 - cargas como ensamblaje x64; no se cargará desde un proceso x86
+4

Esta regla tiene sentido para mí. Pero tenga en cuenta la siguiente situación: Native.dll (x64) utilizado por NetA.dll (Cualquier CPU) utilizado por NetB.dll (Cualquier CPU) utilizado por App1.exe (x64). No hay ningún problema real aquí, pero la compilación de 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 se compila la compilación de NetB.dll. Quiero mantener NetB.dll como "Cualquier CPU" porque es un ensamblado común utilizado en una aplicación diferente, pura-dot-net. Concluyo que mi única opción es suprimir/ignorar la advertencia. ¿Sí? –

+1

Debido a la dependencia de Native.dll, toda su línea de ensamblado/aplicación 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) ensamblar 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 cargará –

0

Debería haber una manera de hacer a.NET EXE/DLL AnyCPU y cualquier archivo DLL no administrado depende de compilado ambos con x86 y x64, ambos empaquetados quizás con diferentes nombres de archivo y luego el módulo .NET carga dinámicamente el correcto basado en su arquitectura de procesador de tiempo de ejecución. Eso haría AnyCPU poderoso. Si la DLL de C++ solo es compatible con x86 o x64, AnyCPU no tiene sentido. Pero el paquete de ambas ideas todavía no se ha implementado 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 agrupamiento múltiple que permita AnyCPU o incluso otros conceptos como cualquier configuración.

+2

¡Bienvenido a stackoverflow! ¿Puedes intentar enfocar/reformatear esta respuesta un poco? –

+0

Parece que sería una buena pregunta, o una publicación de blog o una solicitud de función en Connect ... en realidad no responde a esta. –

1

Para mi proyecto, tengo el requisito de poder construir tanto para x86 como para x64. El problema con esto es que siempre que agrega referencias mientras usa una, entonces se queja cuando construye la otra.

Mi solución es editar manualmente los archivos * .csproj modo que las líneas como éstas:

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

se cambian a esto:

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

había problema similar que fue causado por la EM UNIDAD Prueba DLL. Mi aplicación WPF se compiló como x86 pero la DLL de prueba unitaria (archivo EXE referenciado) como "Cualquier CPU". Cambié la DLL de prueba unitaria que se compilaría para x86 (igual que EXE) y se resolvió.

3

Además de respuesta David Sacks, es posible que también tenga que ir a la pestaña de la BuildProject Properties y establecer Platform Target a x86 para el proyecto que le está dando a estas advertencias. Aunque es de esperar que lo sea, esta configuración no parece estar perfectamente sincronizada con la configuración en el administrador de configuración.

0

Tuve una advertencia muy similar en mi compilación. Mis proyectos se configuraron para destino .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 alcanzar .NET 4.5.1 (no fue un problema para mí, fue para una aplicación completamente nueva), ya no recibí la advertencia ...

0

Resolví esta advertencia cambiando la configuración Gerente "para lanzar (Plataforma mixta).

0

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

1

que estaba recibiendo la misma advertencia que hice esto: Descargar proyecto

1) propiedades 2) edición del proyecto es decir .csproj 3> Agregar comando de seguimiento

4) proyecto Recargar 5) Listo. ..

<PropertyGroup> 
<ResolveAssemblyWarnOrErrorOnTargetArchitectureMismatch> 
None 
</ResolveAssemblyWarnOrErrorOnTargetArchitectureMismatch> 
</PropertyGroup> 
+0

Esto no resuelve el problema. Es solo desactivar la advertencia para el proyecto en particular. Pero en algunos casos, creo que es una solución válida. ¡Gracias! – Tiny

2

tuve este problema hoy en día y con sólo mirar las configuraciones de edificio en Visual Studio no estaba ayudando porque demostró Cualquier CPU tanto para el proyecto que no estaba construyendo y el refere proyecto nced.

Entonces miré en el csproj del proyecto de referencia y encontramos este:

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

alguna manera este PlatformTarget consiguió añadió en medio de un cambio de configuración y el IDE no parecía ver eso.

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

0

Tuve el mismo problema con la conexión de apertura de SQLite, ¡y el uso de Nuget y la instalación del componente utilizado en el proyecto (SQLite) lo arreglaron! intente instalar su componente de esta manera y verifique el resultado

Cuestiones relacionadas