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

Pau*_*und 442 .net visual-studio

我是Visual Studio 2010中的项目配置的新手,但我做了一些研究,但仍然不能完全解决这个问题.我有一个Visual Studio解决方案,其中包含引用C#DLL的C++ DLL.C#DLL引用了一些其他的DLL,一些在我的项目中,一些在外部.当我尝试编译C++ DLL时,我收到此警告:

警告MSB3270:正在构建"MSIL"的项目的处理器体系结构与参考"[internal C#dll]","x86"的处理器体系结构之间存在不匹配.

它告诉我去配置管理器来调整我的架构.C#DLL使用平台目标x86进行设置.如果我尝试将其更改为其他内容,例如Any CPU,则会抱怨,因为它所依赖的外部DLL之一具有平台目标x86.

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

我在这做错了什么?

Dav*_*cks 491

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

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

  1. 转到"生成"|"配置管理器"菜单项.
  2. 在列表中找到您的项目,在Platform下它会说"Any CPU"
  3. 从下拉列表中选择"Any CPU"选项,然后选择 <New..>
  4. 从该对话框中,从"New Platform"下拉列表中选择x86,并确保在"Copy settings from"下拉列表中选择"Any CPU".
  5. 点击OK
  6. 您需要为Debug和Release配置选择x86.

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

另外请注意,如果项目是纯.NET项目,项目通常可以兼容"任何CPU".如果您引入针对特定处理器体系结构的依赖项(第三方DLL或您自己的C++托管项目),则只会出现此问题.

  • 它很可能会伤害到某些东西.任何CPU exe都将在64位操作系统上加载为x64,并且无法加载x86 dll.因此,如果您依赖特定平台,那么您应该正确设置平台. (6认同)
  • 我刚刚安装了Visual Studio 2012的RTW并打开了一个预先存在的2010解决方案并开始看到相同的警告,因此它仍然存在于RTW中. (3认同)
  • 话虽如此,我认为大卫的答案是正确的,这个警告让你知道你的应用程序真的不是"AnyCPU",所以当你最终将它部署到错误的架构时,你会遇到问题. (3认同)
  • 请注意,如果您使用 Visual Studio 中的 Windows 窗体设计器(仅限 x86),则从“任何 CPU”更改为“x64”可能会导致设计器停止工作。 (2认同)

Gio*_*ino 137

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

由于我无法更改我正在引用的MS库,并且因为我知道我的目标部署环境将只是64位,所以我可以放心地忽略这个问题.

警告怎么样?微软在回复Connect报告时发布了一个选项是禁用该警告.您应该这样做,因为您非常了解您的解决方案体系结构,并且您完全了解您的部署目标,并且知道它在开发环境之外并不是真正的问题.

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

<PropertyGroup>
  <ResolveAssemblyWarnOrErrorOnTargetArchitectureMismatch>None</ResolveAssemblyWarnOrErrorOnTargetArchitectureMismatch>
</PropertyGroup>
Run Code Online (Sandbox Code Playgroud)

  • "我的项目平台是AnyCPU,我正在引用为AMD64构建的MS库"......这是错误的.由于您的目标部署始终是64位,因此您可以将平台设置为x64,如果您的64位假设被违反,则会产生更合适的错误,并且还会阻止警告. (6认同)
  • 这可行,但不适用于警告的变体:"引用的程序集...针对与应用程序不同的处理器".如果这个警告有类似的设置,那会很棒吗? (4认同)
  • @BenVoigt理论上是一个好主意,但VS是一个x86进程需要x86构建的控件来运行像Windows Forms Designer这样的东西,即使你的应用程序只有64位.使用虚假的"任何CPU"构建是一个有效但不幸的理由. (2认同)

Gus*_*ori 60

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

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

当您将EXE构建为AnyCPU时,您所做的就是推迟决定使用什么进程位来操作OS,这将使EXE符合它的喜好.也就是说,x64操作系统将创建一个64位进程,x86操作系统将创建一个32位进程.

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

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

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

  • 这条规则对我有意义.但请考虑以下情况:App1.exe(x64)使用的NetB.dll(任何CPU)使用的NetA.dll(任何CPU)使用的Native.dll(x64).这里没有真正的问题,但编译NetA.dll会给我警告.好的,因为这个程序集直接依赖于Native.dll,我也可以将它标记为x64.但随后编译NetB.dll抱怨.我想将NetB.dll保持为"任何CPU",因为它是在不同的纯点网应用程序中使用的常见程序集.我的结论是,我唯一的选择是压制/忽略警告.是? (4认同)
  • 由于依赖于Native.dll,您的整个应用程序/程序集谱系现在都是x64,无论您是否禁止警告.虽然抑制在您的场景中起作用,但未来可能会出现奇怪的情况.例如,1)程序集NetB在x86环境中使用,其中Nativex64不会加载,或者2)您的客户需要x86版本的App1.exe,并且您可以愉快地编译,因为NetB被标记为任何CPU,但是,堆栈顶部的Nativex64将无法加载 (2认同)

Han*_*ant 23

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

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

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

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

只是解决问题.将EXE项目的Platform目标设置为x86,它不能与任何其他设置一起使用.并将所有DLL项目保留在AnyCPU.


小智 8

我得到了同样的警告,我这样做了:

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

    <PropertyGroup>
        <ResolveAssemblyWarnOrErrorOnTargetArchitectureMismatch>
            None
        </ResolveAssemblyWarnOrErrorOnTargetArchitectureMismatch>
    </PropertyGroup>
    
    Run Code Online (Sandbox Code Playgroud)
  4. 重新加载项目

  • 这不是解决问题。它只是禁用特定项目的警告。但在某些情况下,我发现它是一个有效的解决方案。谢谢! (2认同)

Sid*_*dex 6

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

  • Directory.Build.props文件添加到您的解决方案文件夹
  • 将其粘贴到其中:
<Project>
 <PropertyGroup>
   <ResolveAssemblyWarnOrErrorOnTargetArchitectureMismatch>None</ResolveAssemblyWarnOrErrorOnTargetArchitectureMismatch>
 </PropertyGroup>
</Project>
Run Code Online (Sandbox Code Playgroud)


小智 5

我今天遇到了这个问题,只是在 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>
Run Code Online (Sandbox Code Playgroud)

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

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