如何解决Visual Studio编译错误“处理器体系结构之间的不匹配”?
我是Visual Studio 2010中的项目configuration新手,但是我已经做了一些研究 ,但仍然无法完全解决这个问题。 我有一个C ++ DLL引用C#DLL的Visual Studio解决scheme。 C#DLL引用了一些其他的DLL,一些在我的项目和一些外部。 当我尝试编译C ++ DLL时,我得到这个警告:
警告MSB3270:构build“MSIL”的项目的处理器体系结构与参考“[internal C#dll]”,“x86”的处理器体系结构之间存在不匹配。
它告诉我去configurationpipe理器来调整我的架构。 C#DLL使用平台目标x86进行设置。 如果我试图改变这个东西,像任何CPU,它抱怨,因为它所依赖的外部DLL之一有平台目标x86。
当我看看configurationpipe理器时,它将C#DLL的平台显示为x86,并将我的C ++项目显示为Win32。 这似乎是正确的设置; 当然我不希望我的C ++项目的项目将平台设置为x64,这是唯一提供的其他选项。
我在这里做错了什么?
这个警告似乎是在新的Visual Studio 11 Beta和.NET 4.5中引入的,尽pipe我想这可能是以前可能的。
首先,这只是一个警告。 如果你只是处理x86的依赖关系,它不应该伤害任何东西。 当您声明您的项目与“任何CPU”兼容,但是您依赖于x86或x64的项目或.dll程序集时,Microsoft只是试图警告您。 因为你有一个x86的依赖,在技术上你的项目不是“任何CPU”兼容。 要使警告消失,实际上应该将项目从“任何CPU”更改为“x86”。 这很容易做,这里是步骤。
- 转到Build | Configuration Manager菜单项。
- 在列表中find您的项目,在平台下,它会说“任何CPU”
- 从下拉菜单中select“Any CPU”选项,然后select
<New..>
- 在该对话框中,从“New Platform”下拉列表中selectx86,并确保在“Copy settings from”下拉列表中select了“Any CPU”。
- 点击确定
- 您将要为Debug和Releaseconfigurationselectx86。
这将使警告消失,并且声明您的程序集或项目现在不再是“任何CPU”兼容,但现在是x86特定的。 如果您正在构build具有x64依赖项的64位项目,这也适用; 你只需要selectx64。
还有一点需要注意的是,如果项目是纯.NET项目,项目通常可以兼容“任何CPU”。 如果你引入了一个依赖项(第三方dll或你自己的C ++pipe理的项目),这个问题只会出现在针对特定处理器体系结构。
这是一个非常固执的警告,虽然这是一个有效的警告,但有些情况下,由于使用第三方组件和其他原因无法解决。 我有一个类似的问题,除了这个警告是因为我的项目平台是AnyCPU,而且我引用了为AMD64构build的MS库。 这是在Visual Studio 2010中,似乎是通过安装VS2012和.Net 4.5引入的。
由于我无法更改引用的MS库,并且由于我知道我的目标部署环境只能是64位,所以我可以放心地忽略这个问题。
那警告怎么样? 微软发布了一个连接报告 ,其中一个选项是禁用该警告。 你应该这样做,你是非常了解你的解决scheme架构,你完全理解你的部署目标,并知道这不是一个真正的问题以外的开发环境。
您可以编辑您的项目文件并添加此属性组,并设置为禁用警告:
<PropertyGroup> <ResolveAssemblyWarnOrErrorOnTargetArchitectureMismatch>None</ResolveAssemblyWarnOrErrorOnTargetArchitectureMismatch> </PropertyGroup>
一个好的经验法则是“打开的DLL,closures的EXE”,即:
- EXE通过指定x86或x64来定位操作系统。
- DLL是保持开放的(即AnyCPU),所以它们可以在32位或64位进程中实例化。
当您将EXE构build为AnyCPU时,您所做的只是推迟对操作系统使用何种进程位的决定,这将会使EXE受到欢迎。 也就是说,一个x64操作系统将创build一个64位的进程,一个x86操作系统将创build一个32位的进程。
构buildDLL作为AnyCPU使其兼容任一进程。
有关assembly加载细节的更多信息,请参见此处 。 执行摘要如下所示:
- AnyCPU – 根据调用过程加载为x64或x86程序集
- x86 – 作为x86程序集加载; 将不会从x64进程加载
- x64 – 加载为x64程序集; 将不会从x86进程加载
C#DLL使用平台目标x86进行设置
这是一个问题,一个DLL实际上并不能select进程的位数。 这完全取决于EXE项目,这是第一个被加载的程序集,所以它的平台目标设置是统计和设置进程的位数。
DLL没有select,它们需要与进程位相兼容。 如果他们不是,那么当你的代码尝试使用它们时,你会得到一个带有BadImageFormatException的大的Kaboom。
所以对于DLL的一个很好的select是AnyCPU,所以它们以任何方式工作。 这对于C#DLL很有意义,它们都可以工作。 但是当然,不是你的C ++ / CLI混合模式DLL,它包含非托pipe代码,只有当进程以32位模式运行时才能正常工作。 你可以让构build系统产生警告。 这正是你得到的。 只是警告,它仍然正确地build立。
只是解决这个问题。 设置EXE项目的平台目标为x86,它不会与任何其他设置。 只要保留所有的DLL项目在AnyCPU。
对于C#项目来说,x86的目标听起来很像。 它说这个程序集只支持x86体系结构。 同样对于x64。 另一方面,任何一个CPU都说我不关心哪个架构,我支持两者。 所以,接下来的两个问题是(1)使用这些dll的可执行文件的configuration是什么? 和(2)你的OS /计算机的位数是多less? 我问的原因是因为如果你的可执行文件被编译为64位运行,那么它需要所有的依赖关系能够以64位模式运行。 您的任何CPU程序集都应该能够被加载,但也许它是引用了一些只能在x86configuration下运行的其他依赖。 如果您计划在64位模式下运行可执行文件,请检查所有依赖项和依赖关系,以确保所有内容都是“任意CPU”或“x64”。 否则,你会有问题。
在许多方面,Visual Studio不会编译任何CPU和各种体系结构相关程序集的混合。 这是可行的,但是它通常要求一个本来是“任何CPU”的程序集必须分别编译为x86和x64,因为某个依赖项的某个依赖项有两个版本。
除了David Sacks的回答之外,还可能需要转到Project Properties
的Build
选项卡,并将Platform Target
设置为x86
,以便为您提供这些警告的项目。 虽然你可能会期望它,但是这个设置似乎并不完全与configurationpipe理器中的设置同步。
我今天有这个问题,只是看在Visual Studio中的build筑configuration没有帮助,因为它显示任何CPU不是build设的项目和引用的项目。
然后我查看了引用项目的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被添加到configuration更改的中间,IDE似乎没有看到它。
从被引用的项目中删除这一行解决了我的问题。
如果您的C#DLL具有基于x86的依赖关系,那么您的DLL本身将必须是x86。 我真的没有看到这样的方式。 VS抱怨将其更改为(例如)x64,因为64位可执行文件无法加载32位库。
我有点困惑的C + +项目的configuration。 为构build提供的警告消息表明它是针对AnyCPU的,因为它报告了它所针对的平台是[MSIL],但是您表示该项目的configuration实际上是Win32。 本机Win32应用程序不应该涉及MSIL – 尽pipe如果它正在与C#库进行交互,可能需要启用CLR支持。 所以我认为信息方面有一些差距。
我是否可以恭敬地邀请您审核并发布项目的确切configuration以及它们之间的相互关系? 如果可能的话,高兴地进一步帮助。
我以前有过类似的问题,尤其是在将testing解决scheme添加到现有的x64解决scheme(如SharePoint)时。 就我而言,似乎与某些项目模板默认添加为某些平台的事实有关。
以下是经常适用于我的解决scheme:在configurationpipe理器(“configurationpipe理器”(活动configuration下拉菜单,通常称为“debugging”,是实现该目标的好方法)和项目平台(在项目属性中)build立,然后把所有的东西都放回AnyCPU。 有时我必须删除并重新添加一些依赖项(每个项目属性中的DLL),有时需要更改“在32位或64位进程中运行testing”(双击Local.testsettings并转到主机)。
在我看来,这只是设置一些东西,然后把它放回去,但是我可能在幕后发生了更多的事情,我没有看到。 虽然过去对我来说相当稳定。
对于我的项目,我有一个要求,可以build立到x86和x64。 这个问题是,每当你使用一个引用时添加引用,那么当你build立另一个时,它会抱怨。
我的解决scheme是手动编辑* .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"/>
你也可能会得到这个MS Fakes程序集的警告,因为f.csproj是build立在命令上的,所以不容易解决。 幸运的是,FIX XML允许你在那里添加它 。
应该有一种方法来创build一个.NET EXE / DLL AnyCPU,以及任何非托pipe的DLL,它们都依赖于x86和x64编译,两者都捆绑了不同的文件名,然后.NET模块根据运行时dynamic加载正确的DLL处理器架构。 这将使AnyCPU强大。 如果C ++ DLL仅支持x86或x64,那么AnyCPU当然毫无意义。 但捆绑这两个想法,我还没有看到作为configurationpipe理器实现,甚至没有提供一种方法来build立同一个项目两次与不同的configuration/平台多个捆绑允许AnyCPU甚至其他概念,如任何configuration是可能的。
我有类似的问题,这是由MSunit testingDLL引起的。 我的WPF应用程序被编译为x86,但unit testingDLL(引用EXE文件)为“任何CPU”。 我将unit testingDLL更改为x86编译(与EXE相同),并将其解压缩。
我的构build中有一个非常类似的警告。 我的项目被设置为目标.NET 4.5,在生成服务器上安装了Windows 8.1 SDK(用于.NET 4.5.1)。 更新我的项目,以目标.NET 4.5.1(对我来说不是一个问题,是一个全新的应用程序),我没有收到警告了… …
我解决了这个警告改变“configurationpipe理器”释放(混合Plataform)。
在编译SQL Server 2012 SP1 SSISpipe道脚本任务时,我在Visual Studio 2012中得到了此警告 – 直到我安装了SQL Server 2012 SP2。
我得到了这样的警告:
1)卸载项目2)编辑项目属性即.csproj 3>添加跟随标签
4)重新加载项目5)完成…
<PropertyGroup> <ResolveAssemblyWarnOrErrorOnTargetArchitectureMismatch> None </ResolveAssemblyWarnOrErrorOnTargetArchitectureMismatch> </PropertyGroup>
我有与SQLite打开连接相同的问题,并使用Nuget和安装项目中使用的组件(SQLite)修复它! 尝试以这种方式安装您的组件,并检查结果