【问题标题】:How do I fix the Visual Studio compile error, "mismatch between processor architecture"?如何修复 Visual Studio 编译错误“处理器架构之间的不匹配”?
【发布时间】:2012-04-24 04:57:01
【问题描述】:

我是 Visual Studio 2010 中项目配置的新手,但我已经完成了一些 research 并且仍然无法完全解决这个问题。我有一个带有引用 C# DLL 的 C++ DLL 的 Visual Studio 解决方案。 C# DLL 引用了一些其他 DLL,一些在我的项目中,一些在外部。当我尝试编译 C++ DLL 时,我收到以下警告:

警告 MSB3270:正在构建的项目的处理器架构“MSIL”与参考“[internal C# dll]”、“x86”的处理器架构不匹配。

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

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

我在这里做错了什么?

【问题讨论】:

  • 投诉是什么,具体来说,当您将其更改为 Any CPU 时?
  • 我没有足够的信息来提出明智的建议,但请右键单击您的解决方案 -> 项目构建顺序,并确保您的 C# 项目在 C++ 项目之前构建。如果不是,请转到 Dependencies 选项卡,让 VS 知道 C++ 项目依赖于 C# 项目。
  • Visual Studio 在这方面又是一派胡言。我屏幕顶部的平台显示 x64,但警告显示正在构建的项目是“MSIL”。所以 Visual Studio 告诉我,当我不使用苹果时,苹果和橙子之间存在不匹配。我们可以将其重命名为 Visual Stupido 吗?
  • 就我而言,这是 Visual Studio 中的一个错误。我选择 x64 作为平台目标,它告诉我正在为 MSIL 构建项目。
  • 简短的回答是,如果您的项目依赖于 x86 或 x64,则不能使用任何 CPU(仅适用于纯 .NET 应用程序)。所以你必须为 x64 或 x32 构建,而不是任何 CPU。这源自戴夫的answer

标签: .net visual-studio


【解决方案1】:

这个警告似乎是在新的 Visual Studio 11 Beta 和 .NET 4.5 中引入的,尽管我认为以前可能有过。

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

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

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

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

【讨论】:

  • 我刚刚安装了 Visual Studio 2012 的 RTW 并打开了一个预先存在的 2010 解决方案并开始看到相同的警告,所以它仍然存在于 RTW 中。
  • 话虽如此,我认为大卫的回答是正确的,这个警告是让您知道您的应用程序确实不是“AnyCPU”,因此当您最终将其部署到错误的架构时会遇到问题.
  • 它很可能会伤害一些东西。 Any CPU exe 将在 64 位操作系统上加载为 x64,并且无法加载 x86 dll。因此,如果您依赖于特定平台,您真的应该正确设置您的平台。
  • 在 VS C# 2010 Express 中似乎缺少构建菜单。我怎么去呢?我希望他们不要隐瞒事情。
  • 刚刚了解了如何在 Visual Studio 2010 Express 中启用构建菜单:工具菜单 -> 设置 -> 选择“专家设置”
【解决方案2】:

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

由于我无法更改我引用的 MS 库,而且我知道我的目标部署环境永远只能是 64 位,我可以放心地忽略这个问题。

警告呢?微软在回复a Connect report 时发布了一个选项是禁用该警告。只有在您非常了解您的解决方案架构并且您完全了解您的部署目标并且知道这在开发环境之外并不是真正的问题时,您才应该这样做。

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

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

【讨论】:

  • 我看到的唯一其他官方 MS 引用此解决方案是在 Microsoft .NET Framework 4.5 RC Readme file。奇怪的是,它已从 RTM 自述文件中删除。
  • 这有效,但不适用于警告的变体:“引用的程序集...针对与应用程序不同的处理器”。如果这个警告有类似的设置就好了?
  • “我的项目平台是 AnyCPU,我正在引用为 AMD64 构建的 MS 库”...这是错误的。由于您的目标部署始终是 64 位,您可以将您的平台设置为 x64,如果您的 64 位假设被违反,这会产生更合适的错误,并且还可以防止警告。
  • @BenVoigt 在理论上是一个好主意,但 VS 作为 x86 进程需要 x86 控件构建来运行 Windows 窗体设计器之类的东西,即使您的应用程序永远只有 64 位。使用错误的“任何 CPU”构建是一个有效但不幸的理由。
  • @jrh:然后将 GUI 放入 DLL 项目中,并将 that 构建为 AnyCPU。 EXE 需要使用正确的体系结构进行标记以匹配本机依赖项。将 GUI 与逻辑正确分离有很长的路要走(尽管它仍然有其局限性,例如当本机代码呈现 GUI 的一部分时,但是除非您为两者都构建整个项目,否则设计器支持是一个失败的原因x86 和 x64)
【解决方案3】:

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

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

当您将 EXE 构建为 AnyCPU 时,您所做的就是将决定使用哪个进程位数的决定推迟到操作系统,这将使 EXE 按自己的喜好进行 JIT。也就是说,x64 操作系统会创建一个 64 位进程,x86 操作系统会创建一个 32 位进程。

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

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

  • AnyCPU – 根据调用进程加载为 x64 或 x86 程序集
  • x86 – 加载为 x86 程序集;不会从 x64 进程加载
  • x64 – 加载为 x64 程序集;不会从 x86 进程加载

【讨论】:

  • 这条规则对我来说很有意义。但请考虑以下情况: NetA.dll (Any CPU) 使用的 Native.dll (x64) App1.exe (x64) 使用的 NetB.dll (Any CPU) 使用。这里没有真正的问题,但是编译 NetA.dll 给了我警告。好的,因为这个程序集直接依赖于 Native.dll,我也可以将它标记为 x64。但随后编译 NetB.dll 抱怨。我想将 NetB.dll 保留为“任何 CPU”,因为它是在不同的纯点网应用程序中使用的通用程序集。我得出结论,我唯一的选择是抑制/忽略警告。是吗?
  • 由于对 Native.dll 的依赖,您的整个应用程序/程序集血统现在是 x64,无论您是否抑制警告。虽然抑制在您的场景中有效,但将来可能会出现奇怪的情况。例如,1) 程序集 NetB 用于 x86 环境,其中 Nativex64 不会加载,或者 2) 您的客户想要一个 x86 版本的 App1.exe,并且您编译愉快,因为 NetB 被标记为任何 CPU,但同样,栈顶的 Nativex64 不会加载
  • 虽然 Gustavo 的规则是一个很好的原则,但它不能用于这个问题中提出的特定问题,因为该项目已经依赖于不遵循规则的 3rd 方程序集(它是 x86 ,而不是任何CPU)。因此,只要存在依赖项,整个项目链就必须以 x86 为目标。
【解决方案4】:

C# DLL 设置为平台目标 x86

这是一个问题,DLL 实际上并不能选择进程的位数。这完全由 EXE 项目决定,这是第一个加载的程序集,因此它的平台目标设置是计算和设置进程位数的那个。

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

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

只是解决问题。将 EXE 项目的平台目标设置为 x86,它不会与任何其他设置一起使用。只需将所有 DLL 项目保存在 AnyCPU。

【讨论】:

  • 所以,要明确一点:我不是在构建 EXE,而是在构建一个 DLL,以便与其他人的 EXE 一起运行。将 C# DLL 的平台目标更改为 Any CPU 并不能消除警告。我想知道这是否是connect.microsoft.com/VisualStudio/feedback/details/728901/… 的情况——我会忽略警告本身,但实际上 EXE 能够加载 C# DLL 但不能加载 C++ DLL,所以我认为这是一个真正的问题。
  • 你真的在用VS2010吗?也不清楚您无法加载 C++/CLI DLL。什么是诊断?使用这些重要信息更新您的问题。
  • 没有发布关于加载失败的信息,因为我不是 100% 确定它是否已连接,并且在进一步调试时结果并非如此。我正在使用VS2010。更新了问题文本。很抱歉造成混乱
  • 您没有记录与加载 DLL 相关的任何类型的错误或异常。如果你不告诉我你知道什么,我无法帮助你。祝你好运。
【解决方案5】:

我收到了同样的警告:

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

    <PropertyGroup>
        <ResolveAssemblyWarnOrErrorOnTargetArchitectureMismatch>
            None
        </ResolveAssemblyWarnOrErrorOnTargetArchitectureMismatch>
    </PropertyGroup>
    
  4. 重新加载项目

【讨论】:

  • 这并不能解决问题。它只是禁用特定项目的警告。但在某些情况下,我发现它是一个有效的解决方案。谢谢!
【解决方案6】:

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

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

【讨论】:

  • 我花了一整天的时间才弄明白。非常感谢! :)
【解决方案7】:

使用https://docs.microsoft.com/en-us/visualstudio/msbuild/customize-your-build#directorybuildprops-example:

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

【讨论】:

    【解决方案8】:

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

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

    我能否请您查看并发布更多关于项目的确切配置以及它们如何相互关联的详细信息?如果可能的话,很乐意提供进一步的帮助。

    【讨论】:

      【解决方案9】:

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

      【讨论】:

        【解决方案10】:

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

        在许多方面,Visual Studio 无法轻松地编译任何 CPU 和各种依赖于体系结构的程序集的混合体。这是可行的,但它通常要求必须为 x86 和 x64 分别编译一个原本是“任何 CPU”的程序集,因为某处的某些依赖项有两个版本。

        【讨论】:

        • 可执行文件的配置是否相关,因为我在尝试构建 DLL 时遇到了失败? (虽然是 x86。)我的电脑是 x64。
        • 它是决定使用什么bitness的可执行文件。如果可执行文件作为 x64 运行,那么它加载的任何东西(直接或间接)都必须是 x64 或 Any CPU。如果可执行文件作为 x86 运行,那么任何加载(直接或间接)都必须是 x86 或 Any CPU。
        【解决方案11】:

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

        以下是通常对我有用的解决方案:在配置管理器中将所有内容设置为正确的平台(活动配置下拉菜单,通常说调试,是一个很好的方法)和项目平台(在项目属性中),然后构建,然后将所有内容设置回 AnyCPU。有时我必须删除并重新添加一些依赖项(每个项目的属性中的 DLL),有时必须更改“在 32 位或 64 位进程中运行测试”(双击 Local.testsettings 并转到主机)。

        在我看来,这只是在设置一些东西,然后再将其设置回去,但幕后可能还有更多我没有看到的事情。不过,它在过去对我来说相当一致。

        【讨论】:

          【解决方案12】:

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

          【讨论】:

            【解决方案13】:

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

            【讨论】:

              【解决方案14】:

              对于 MS Fakes 程序集,您也可能会收到此警告,由于 f.csproj 是基于命令构建的,因此该程序集不容易解决。幸运的是the Fakes xml allows you to add it in there

              【讨论】:

                【解决方案15】:

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

                【讨论】:

                  【解决方案16】:

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

                  【讨论】:

                    【解决方案17】:

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

                    【讨论】:

                      【解决方案18】:

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

                      【讨论】:

                        【解决方案19】:

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

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

                        【讨论】:

                          【解决方案20】:

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

                          【讨论】:

                          • 欢迎来到stackoverflow!你能试着集中/重新格式化这个答案吗?
                          • 这听起来像是一个很好的问题,或者博客文章或 Connect 上的功能请求......它实际上并没有回答这个问题。
                          猜你喜欢
                          • 1970-01-01
                          • 1970-01-01
                          • 2023-04-06
                          • 1970-01-01
                          • 1970-01-01
                          • 1970-01-01
                          • 2018-06-26
                          • 2012-07-26
                          • 1970-01-01
                          相关资源
                          最近更新 更多