如何解决Visual Studio编译错误,即“处理器体系结构之间的不匹配”?


458

我是Visual Studio 2010中项目配置的新手,但我进行了一些研究,但仍然无法完全弄清楚这个问题。我有一个Visual Studio解决方案,其中包含引用C#DLL的C ++ DLL。C#DLL引用了其他一些DLL,其中一些在我的项目中,而另一些在外部。当我尝试编译C ++ DLL时,出现以下警告:

警告MSB3270:正在构建的项目“ MSIL”的处理器体系结构与引用“ [内部C#dll]”,“ x86”的处理器体系结构之间不匹配。

它告诉我去配置管理器来调整我的体系结构。使用平台目标x86设置C#DLL。如果我尝试将其更改为其他任何东西,例如Any CPU,它会抱怨,因为依赖的外部DLL之一具有平台目标x86。

当我查看Configuration Manager时,它显示了我的C#DLL的平台为x86,以及我的C ++项目的平台为Win32。这似乎是正确的设置。当然,我不希望我的C ++项目的项目平台设置为x64,这是唯一提供的其他选项。

我在这里做错了什么?


当您将其更改为“ Any CPU”时,会有什么抱怨?
lordcheeto 2012年

2
我没有足够的信息来提出有根据的建议,但是请右键单击您的解决方案-> Project Build Order,并确保在C ++项目之前先构建您的C#项目。如果不是,请转到“依赖关系”选项卡,并让VS知道C ++项目依赖于C#项目。
lordcheeto 2012年

2
Visual Studio再次对此胡扯。屏幕顶部的平台显示x64,但警告显示正在构建的项目为“ MSIL”。因此,Visual Studio告诉我,当我不使用苹果时,苹果和橘子之间不匹配。我们可以将其重命名为Visual Stupido吗?
Paul McCarthy

就我而言,这是Visual Studio中的错误。我选择x64作为平台目标,它告诉我我正在为MSIL构建该项目。
Paul McCarthy

简短的答案是,如果您的项目依赖于x86或x64,则不能使用Any CPU(仅适用于纯.NET应用程序)。因此,您必须为x64或x32而不是任何CPU进行构建。这是从Dave的答案
-zar

Answers:


512

尽管我认为以前可能已经实现了,但新的Visual Studio 11 Beta和.NET 4.5似乎已经引入了此警告。

首先,这实际上只是一个警告。如果您仅处理x86依赖项,那么它不会有任何伤害。当您声明您的项目与“任何CPU”兼容,但您依赖于x86或x64的项目或.dll程序集时,Microsoft只是试图警告您。因为您具有x86依赖性,所以从技术上讲,您的项目因此不兼容“任何CPU”。为了消除警告,您实际上应该将项目从“ Any CPU”更改为“ x86”。这很容易做到,这里是步骤。

  1. 转到“构建|配置管理器”菜单项。
  2. 在列表中找到您的项目,在“平台”下它将显示“ Any CPU”
  3. 从下拉列表中选择“任何CPU”选项,然后选择 <New..>
  4. 在该对话框中,从“新平台”下拉列表中选择x86,并确保在“从以下位置复制设置”下拉列表中选择了“任何CPU”。
  5. 点击确定
  6. 您将要同时为调试和发布配置选择x86。

这将使警告消失,并声明您的程序集或项目现在不再与“任何CPU”兼容,而是特定于x86。如果您要构建具有x64依赖项的64位项目,这也适用。您只需选择x64。

另一个要注意的是,如果项目是纯.NET项目,则它们通常可以“兼容任何CPU”。仅当您引入针对特定处理器体系结构的依赖项(第三方dll或您自己的C ++托管项目)时,才会出现此问题。


3
我刚刚安装了Visual Studio 2012的RTW,并打开了一个预先存在的2010解决方案,并开始看到相同的警告,因此RTW中仍然存在该警告。
Tod Thomson

4
话虽如此,我认为David的回答是正确的,该警告是让您知道您的应用程序确实不是“ AnyCPU”,因此,当最终将其部署到错误的体系结构时,您会遇到问题。
Tod Thomson 2012年

6
很好地伤害了某些东西。Any CPU exe将在64位操作系统上作为x64加载,并且无法加载x86 dll。因此,如果您对特定平台有依赖性,则应该正确设置平台。
Yaur 2013年

1
VS C#2010 Express中似乎缺少“生成”菜单。我该怎么办?我希望他们不会藏起来。
Xonatron 2013年

1
刚刚发现如何在Visual Studio 2010 Express中启用构建菜单:工具菜单->设置->选择'专家设置'
Xonatron 2013年

144

这是一个非常顽固的警告,尽管它是有效的警告,但在某些情况下,由于使用了第三方组件和其他原因,它无法解决。除了警告是因为我的项目平台是AnyCPU,而且我引用的是为AMD64构建的MS库之外,我有一个类似的问题。顺便说一下,这是在Visual Studio 2010中,并且似乎是通过安装VS2012和.Net 4.5引入的。

由于我无法更改所引用的MS库,并且由于我知道目标部署环境将永远只有64位,因此可以放心地忽略此问题。

那警告呢?Microsoft针对Connect报告发布了一个选项,就是禁用该警告。您只应该这样做,因为您非常了解解决方案体系结构,并且完全了解部署目标,并且知道在开发环境之外这并不是真正的问题。

您可以编辑项目文件并添加此属性组和设置以禁用警告:

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

1
我所见过的对此解决方案唯一的其他官方MS参考是在Microsoft .NET Framework 4.5 RC自述文件中。奇怪的是,它已从RTM自述文件中删除。
JohnC

4
这是可行的,但不适用于警告的变体:“引用的程序集……针对的是与应用程序不同的处理器”。如果此警告有类似的设置,那就好了吗?
Jimmy

6
“我的项目平台是AnyCPU,我引用的是为AMD64构建的MS库”。这是错误的。由于目标部署始终是64位的,因此可以将平台设置为x64,如果违反了64位的假设,这将导致更适当的错误,并且还可以避免警告。
Ben Voigt

2
@BenVoigt理论上是个好主意,但是VS是x86进程,需要x86控件构建才能运行Windows Forms Designer之类的东西,即使您的应用程序只能是64位。使用错误的“任何CPU”版本是有效的,但不幸的原因。
jrh

1
@jrh:然后把GUI在DLL项目,并生成为AnyCPU。EXE需要标记为正确的体系结构以匹配本机依赖项。正确地将GUI与逻辑分离很长的路要走(尽管它仍然有其局限性,例如当本机代码正在呈现GUI的一部分时,但是设计者的支持是一个迷失的原因,除非您同时为这两个项目构建整个项目x86和x64)
Ben Voigt

61

一个好的经验法则是“打开DLL,关闭EXE”,即:

  • EXE通过指定x86或x64为操作系统。
  • DLL保持打开状态(即AnyCPU),因此可以在32位或64位进程中实例化它们。

当您将EXE编译为AnyCPU时,您所做的就是将决定使用哪个进程位数的决定推迟到OS,这将使EXE符合自己的喜好。也就是说,x64 OS将创建一个64位进程,x86 OS将创建一个32位进程。

将DLL构建为AnyCPU可使它们与任一进程兼容。

有关装配件加载细节的更多信息,请参见此处。执行摘要的内容如下:

  • AnyCPU –加载为x64或x86程序集,具体取决于调用过程
  • x86 –作为x86组件加载;不会从x64进程加载
  • x64 –作为x64组件加载;不会从x86进程加载

4
这条规则对我来说很有意义。但是请考虑以下情况:App1.exe(x64)使用的NetA.dll(任何CPU)使用的NetA.dll(x64)。这里没有真正的问题,但是编译NetA.dll给了我警告。好的,因为此程序集直接依赖于Native.dll,所以我也可以将其标记为x64。但是,然后编译NetB.dll抱怨。我想将NetB.dll保留为“任何CPU”,因为它是在不同的纯点网应用程序中使用的通用程序集。我得出的结论是,我唯一的选择是禁止/忽略该警告。是?
Steve Robbins 2015年

2
由于依赖Native.dll,因此无论您是否取消警告,整个应用程序/程序集沿袭现在都是x64。尽管抑制在您的情况下有效,但将来可能会出现奇怪的情况。例如,1)程序集NetB在x86环境中使用,Nativex64将不会加载,或者2)您的客户想要x86版本的App1.exe,并且由于NetB被标记为任何CPU,因此您可以愉快地进行编译,但是, Nativex64在堆栈的顶部将不会加载
古斯塔沃·森

尽管Gustavo的规则是一个很好的原则,但是不能将其用于该问题中提出的特定问题,因为该项目已经依赖于不遵循该规则的第3方程序集(它是x86,而不是AnyCPU)。因此,只要存在依赖关系,整个项目链就必须以x86为目标。
大卫·伯格

23

使用平台目标x86设置C#DLL

这是一种问题,DLL实际上并没有选择进程的位数。这完全由EXE项目决定,这是第一个加载的程序集,因此其Platform目标设置是计算和设置进程位数的程序。

DLL没有选择,它们需要与进程位兼容。如果不是,那么当您的代码尝试使用它们时,您会得到一个带有BadImageFormatException的大Kaboom。

因此,DLL的一个很好的选择是AnyCPU,因此它们可以以任何一种方式工作。对于C#DLL来说,这很有意义,它们可以以任何一种方式工作。但是可以肯定的是,它不是包含C ++ / CLI混合模式DLL的非托管代码,只有在进程以32位模式运行时才能正常运行。您可以使构建系统生成有关此的警告。正是您所得到的。只是警告,它仍然可以正确构建。

只是解决问题。将EXE项目的“平台”目标设置为x86,它将无法与其他任何设置一起使用。并且只需将所有DLL项目保留在AnyCPU中。


1
因此,需要明确的是:我不是在构建EXE,而是在构建要与其他人的EXE一起运行的DLL。将C#DLL的平台目标更改为“任何CPU”并不能消除该警告。我想知道这是否是connect.microsoft.com/VisualStudio/feedback/details/728901/…的情况–我会忽略警告本身,但实际上EXE能够加载C#DLL,但不能加载C ++ DLL所以我认为这是一个真正的问题。
Paul Eastlund '04年

实际上,您是否在使用VS2010?还不清楚您是否无法加载C ++ / CLI DLL。诊断是什么?使用此基本信息更新您的问题。
汉斯·帕桑

尚未发布有关负载故障的信息,因为我不确定100%是否已连接该负载,而在进一步调试后发现事实并非如此。我正在使用VS2010。更新了问题文本。非常抱歉给您带来混乱
Paul Eastlund 2012年

1
您没有记录任何与加载DLL相关的错误或异常。如果您不告诉我您所知道的信息,我将无能为力。祝你好运。
汉斯·帕桑

5

我收到了同样的警告:

  1. 卸载项目
  2. 编辑项目属性,即.csproj
  3. 添加以下标签:

    <PropertyGroup>
        <ResolveAssemblyWarnOrErrorOnTargetArchitectureMismatch>
            None
        </ResolveAssemblyWarnOrErrorOnTargetArchitectureMismatch>
    </PropertyGroup>
  4. 重新载入专案


2
这不能解决问题。它只是禁用特定项目的警告。但是在某些情况下,我发现它是有效的解决方案。谢谢!
微小的

4

我今天遇到了这个问题,只是看着Visual Studio中的构建配置没有帮助,因为它为未构建的项目和引用的项目都显示了任何CPU。

然后,我查看了所引用项目的csproj,发现了这一点:

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

不知何故,这个PlatformTarget在配置更改的中间被添加了,而IDE似乎没有看到它。

从引用的项目中删除此行解决了我的问题。


我花了整整一天的时间来解决这个问题。非常感谢!:)
SohamC

3

如果您的C#DLL具有基于x86的依赖项,则您的DLL本身将必须是x86。我真的没有办法解决。VS抱怨将其更改为(例如)x64,因为64位可执行文件无法加载32位库。

我对C ++项目的配置有些困惑。为该构建提供的警告消息表明它是针对AnyCPU的,因为它报告的目标平台是[MSIL],但是您指出该项目的配置实际上是Win32。本机Win32应用程序不应包含MSIL-尽管如果它与C#库进行交互,则可能需要启用CLR支持。因此,我认为信息方面存在一些差距。

我能否请您回顾并发布更多有关项目的确切配置以及它们如何相互关联的详细信息?如果可能,很高兴为您提供进一步的帮助。


3

除了大卫·萨克斯的回答,您可能还需要去Build的选项卡Project Properties,并设置Platform Targetx86为是给你这些警告的项目。尽管您可能期望如此,但此设置似乎与配置管理器中的设置并不完全同步。


2

对于C#项目,x86的目标听起来像是。它说该程序集仅支持x86体系结构。对于x64同样。另一方面,任何CPU都说我不在乎哪种架构,我都支持。因此,接下来的两个问题是(1)使用这些dll的可执行文件的配置是什么?和(2)什么是位数您的操作系统/计算机?我问的原因是因为如果您的可执行文件被编译为可在64位模式下运行,则它需要所有依赖项才能在64位模式下运行。您的Any CPU程序集应该能够被加载,但是也许它引用了其他一些只能在x86配置中运行的依赖项。如果计划以64位模式运行可执行文件,请检查所有依赖关系和依赖关系,以确保所有内容都是“ Any CPU”或“ x64”。否则,您将遇到问题。

在许多方面,Visual Studio都不容易混合任何CPU和依赖于各种体系结构的程序集。这是可行的,但是它通常要求必须为x86和x64分别编译否则将是“任何CPU”的程序集,因为某个地方的某些依赖项具有两个版本。


自从尝试构建DLL失败时,可执行文件的配置是否相关?(虽然是x86。)我的电脑是x64。
Paul Eastlund '04年

2
它是确定将使用哪种位数的可执行文件。如果可执行文件以x64运行,则其(直接或间接)加载的任何内容都必须是x64或Any CPU。如果可执行文件以x86运行,则任何负载(直接或间接)必须是x86或Any CPU。
乔纳森·德卡洛

1

我以前也遇到过类似的问题,特别是在将测试解决方案添加到现有x64解决方案(如SharePoint)时。就我而言,这似乎与以下事实有关:默认情况下将某些项目模板添加为某些平台。

这是最适合我的解决方案:在Configuration Manager中将所有内容都设置到正确的平台(“调试”通常说是活动的配置下拉列表,是获得此信息的好方法)和项目平台(在项目属性中),然后构建,然后将所有内容都设置回AnyCPU。有时我必须删除并重新添加一些依赖项(每个项目的属性中的DLL),有时必须更改“以32位或64位进程运行测试”(双击Local.testsettings并转到Hosts)。

在我看来,这只是设置某些内容然后将其重新设置,但是在幕后,我可能还没有看到更多的消息。过去,它对我来说一直很稳定。


1

对于我的项目,我要求能够同时构建到x86和x64。问题在于,每当您在使用一个引用时添加引用,然后在构建另一个引用时就会抱怨。

我的解决方案是手动编辑* .csproj文件,以便如下所示:

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

更改为:

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

1

我有类似的问题,它是由MS UNIT Test DLL引起的。我的WPF应用程序被编译为x86,但是单元测试DLL(引用的EXE文件)被编译为“任何CPU”。我更改了要为x86编译的单元测试DLL(与EXE相同),并且重新设计了它。



0

应该有一种方法可以使.NET EXE / DLL AnyCPU及其依赖于x86和x64编译的所有非托管DLL,都可能捆绑有不同的文件名,然后.NET模块根据其运行时动态加载正确的DLL。处理器架构。那将使AnyCPU功能强大。如果C ++ DLL仅支持x86或x64,则AnyCPU当然毫无意义。但是我尚未看到将两个想法捆绑在一起作为配置管理器实现,甚至都没有提供使用不同的配置/平台两次构建同一项目的方法,以实现多个捆绑,从而允许AnyCPU甚至其他概念(如任何配置)成为可能。


2
欢迎来到stackoverflow!您可以试着集中解决这个问题吗?
Corley Brigman 2013年

这听起来像是一个很好的问题,或者是有关Connect的博客文章或功能请求……实际上并不能回答这个问题。
Ben Voigt

0

我在构建中也有类似的警告。我的项目设置为目标.NET 4.5,在构建服务器上安装了Windows 8.1 SDK(用于.NET 4.5.1)。将项目更新为目标.NET 4.5.1之后(对我来说这不是问题,对于一个全新的应用程序而言),我再也没有收到警告...


0

我已解决此警告,将“ Configuration Manager”更改为Release(混合Plataform)。


0

在编译SQL Server 2012 SP1 SSIS管道脚本任务时,在Visual Studio 2012中收到此警告-直到安装SQL Server 2012 SP2。


0

我在使用SQLite打开连接时遇到了相同的问题,使用Nuget并安装了项目中使用的组件(SQLite)修复了该问题!尝试以这种方式安装组件并检查结果


By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.