如何修复Visual Studio编译错误,“处理器架构不匹配”?

我是Visual Studio 2010项目配置的新手,但我已经做了一些研究,仍然不能完全解决这个问题。我有一个Visual Studio解决方案的c++ DLL引用c# DLL。c# DLL引用了一些其他DLL,一些在我的项目内,一些在外部。当我试图编译c++ DLL时,我得到这个警告:

警告MSB3270:正在构建的“MSIL”项目的处理器架构与参考“[内部c# dll]”,“x86”的处理器架构之间不匹配。

它告诉我去配置管理器调整我的架构。c# DLL是用目标平台x86建立的。如果我尝试将其更改为其他东西,如任何CPU,它会抱怨,因为依赖的外部dll之一具有平台目标x86。

当我查看配置管理器时,它显示了我的c# DLL作为x86和我的c++项目作为Win32的平台。这似乎是正确的设置;当然,我不希望我的c++项目的项目平台设置为x64,这是唯一的其他选项。

我哪里做错了?

439373 次浏览

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

在许多方面,Visual Studio并没有使编译任意CPU和各种依赖于体系结构的程序集的混合变得容易。这是可行的,但它通常要求必须针对x86和x64分别编译“任何CPU”的程序集,因为某个依赖的某个依赖有两个版本。

c# DLL是用目标平台x86建立的

这就是问题所在,DLL实际上无法选择进程的比特数。这完全由EXE项目决定,这是加载的第一个程序集,所以它的平台目标设置是为进程计数和设置位。

dll没有选择,它们需要与进程位相兼容。如果它们不是,那么当你的代码试图使用它们时,你会得到一个大的爆炸和BadImageFormatException。

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

把这个问题撇在一边。将EXE项目的平台目标设置为x86,它将无法与任何其他设置一起工作。并将所有DLL项目保存在AnyCPU中。

这个警告似乎已经在新的Visual Studio 11 Beta和。net 4.5中引入,尽管我认为它以前可能是可能的。

首先,这真的只是一个警告。如果您只是处理x86依赖关系,那么它应该不会有任何损害。当你声明你的项目与“任何CPU”兼容,但你依赖于x86或x64的项目或.dll程序集时,微软只是试图警告你。因为您依赖x86,所以从技术上讲,您的项目不兼容“任何CPU”。为了消除这个警告,你应该把你的项目从“任何CPU”改为“x86”。这很容易做到,以下是步骤。

  1. 转到“构建|配置管理器”菜单项。
  2. 在列表中找到你的项目,在Platform下面会显示Any CPU
  3. 从下拉菜单中选择“Any CPU”选项,然后选择<New..>
  4. 从对话框中,从“New Platform”下拉菜单中选择x86,并确保在“Copy settings From”下拉菜单中选择“Any CPU”。
  5. 点击确定
  6. 调试和发布配置都要选择x86。

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

另外需要注意的是,如果项目是纯。net项目,那么它们通常可以与“任何CPU”兼容。只有当你引入一个针对特定处理器架构的依赖项(第三方dll或你自己的c++托管项目)时,这个问题才会出现。

如果你的c# DLL有基于x86的依赖关系,那么你的DLL本身就必须是x86的。我真不知道还有什么办法。VS抱怨将其更改为(例如)x64,因为64位可执行文件无法加载32位库。

我对c++项目的配置有点困惑。为构建提供的警告消息表明它的目标是AnyCPU,因为它报告的目标平台是[MSIL],但您指出项目的配置实际上是Win32。原生Win32应用程序不应该涉及MSIL——尽管如果它与c#库交互,可能需要启用CLR支持。所以我认为在信息方面存在一些空白。

我能否恭敬地请您回顾并发布更多关于这些项目的确切配置以及它们是如何相互关联的细节?如有可能,我很乐意进一步提供帮助。

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

因为我不能更改我引用的MS库,而且我知道我的目标部署环境永远只能是64位的,所以我可以安全地忽略这个问题。

那警告呢?微软在回应连接报告时表示,一种选择是禁用该警告。只有在非常了解自己的解决方案体系结构、完全理解部署目标并知道在开发环境之外这不是真正的问题时,您才应该这样做。

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

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

我以前遇到过类似的问题,特别是在向现有的x64解决方案(如SharePoint)添加测试解决方案时。在我的例子中,这似乎与默认情况下某些项目模板被添加为某些平台有关。

这里有一个解决方案,通常对我来说是有效的:在配置管理器(active Configuration Manager)和项目平台(在项目属性中)中将所有内容设置为正确的平台(活动配置下拉菜单中显示“正常调试”,这是一种很好的方法),然后构建,然后将所有内容设置为AnyCPU。有时我必须删除并重新添加一些依赖项(每个项目的属性中的dll),有时还必须“在32位或64位进程中运行测试”(双击本地。testsettings和go to Hosts)必须更改。

在我看来,这只是设定了一些事情,然后又把它放回去,但在幕后可能有更多我没有看到的事情发生。不过在过去,这对我来说是相当稳定的。

一个好的经验法则是“打开dll,关闭ex”,也就是说:

  • EXE通过指定x86或x64来针对操作系统。
  • dll是开放的(即AnyCPU),因此它们可以在32位或64位进程中实例化。

当您将EXE构建为AnyCPU时,您所做的一切都是将使用哪个进程位的决定推迟到操作系统,这将JIT EXE到它喜欢的程度。也就是说,x64操作系统将创建64位进程,x86操作系统将创建32位进程。

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

有关程序集加载的更多细节,请参阅在这里。执行摘要如下所示:

  • AnyCPU -加载为x64或x86程序集,取决于调用进程
  • x86 -作为x86程序集加载;不能从x64进程加载
  • x64 -加载为x64程序集;不能从x86进程加载

应该有一种方法可以让. net EXE/DLL成为AnyCPU,以及它依赖的任何非托管DLL都可以用x86和x64编译,两者可能都绑定了不同的文件名,然后. net模块根据其运行时处理器架构动态加载正确的文件名。这将使AnyCPU变得强大。如果c++ DLL只支持x86或x64,那么AnyCPU当然是没有意义的。但是,我还没有看到将两者捆绑的想法实现,因为配置管理器甚至没有提供一种方法,可以使用不同的配置/平台构建两次相同的项目,从而允许AnyCPU或任何配置等其他概念成为可能。

对于我的项目,我要求能够构建到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"/>

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

除了David Sacks的答案,您可能还需要转到Project PropertiesBuild选项卡,并将给您这些警告的项目的Platform Target设置为x86。尽管您可能希望如此,但此设置似乎与配置管理器中的设置并不完全同步。

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

我解决了这个警告,将“配置管理器”更改为发布(混合平台)。

对于MS Fakes程序集,您也可能会收到此警告,因为f.s csproj是基于命令构建的,因此不容易解决。幸运的是# EYZ0。

我在Visual Studio 2012编译SQL Server 2012 SP1 SSIS管道脚本任务时得到了这个警告-直到我安装了SQL Server 2012 SP2。

我得到的警告和我做的一样

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

    <PropertyGroup>
    <ResolveAssemblyWarnOrErrorOnTargetArchitectureMismatch>
    None
    </ResolveAssemblyWarnOrErrorOnTargetArchitectureMismatch>
    </PropertyGroup>
    
  4. Reload the project

我今天遇到了这个问题,只是在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似乎没有看到它。

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

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

使用# EYZ0:

  • 在解决方案文件夹中添加Directory.Build.props文件
  • 把这个粘贴进去:
<Project>
<PropertyGroup>
<ResolveAssemblyWarnOrErrorOnTargetArchitectureMismatch>None</ResolveAssemblyWarnOrErrorOnTargetArchitectureMismatch>
</PropertyGroup>
</Project>

只是想为那些在这里找不到答案的人解决他们的问题。

运行应用程序时,确保正确设置了解决方案平台下拉菜单。我的是在x86上,这反过来又导致了这个问题。

我正在使用IIS Express,对我来说,解决方法是确保我的Web项目将比特位设置为64。

Bitness x64

我只是把平台目标属性改为“任何CPU",这样就完成了! 也许你应该创建一个发布版本。

这样做: # EYZ0 < / p >

平台目标