在x86中编译引用C++/CLI DLL的C#项目时,MSBuild无法生成

本文关键字:项目 MSBuild 编译 x86 引用 C++ DLL CLI | 更新日期: 2023-09-27 18:30:07

我使用的是VS2010和.NET 4.0。

我有两个小项目ABA是一个C++/CLI DLL项目,而B则是引用A的C#EXE项目。两者都必须在x86中编译,因为A使用x86本机dll。

当我使用VS2010 IDE构建B时,B编译良好。接下来,我尝试使用以下命令行使用MSBuild构建B

MSBuild B.csproj/property:平台=x86;配置=释放

并且由于以下错误而失败。

"A.vcxproj"(默认目标)(16)->(InvalidPlatformError目标)->C: ''Program Files(x86)''MSBuild''Microsoft.Cpp''v4.0''Microsoft.Cpp.InvalidPlatform.Targets(23,7):错误MSB8007:项目"A.vcxproj"的平台无效。平台='x86'。您看到此消息可能是因为您正试图在没有解决方案文件,并且已为此项目指定了不存在的非默认平台。[A.vcxproj]

这似乎是因为C++/CLI使用"Win32"作为平台名称,而C#使用"x86"。因此,当我指定"x86"时,它无法构建A。如果为"Win32",则无法生成B

由于自动生成,我不得不使用MSBuild。B的默认平台固定为AnyCPU(我无法更改它),因此我不能使用默认平台技巧,并且在使用MSBuild构建时必须指定"x86"。我该怎么做?有什么方法可以更改平台名称,或者使用MSBuild的更好方法吗?我可以在不使用默认平台的情况下做到这一点吗?

在x86中编译引用C++/CLI DLL的C#项目时,MSBuild无法生成

如果您有一个包含这两个项目的解决方案并对其进行了正确设置,那么您应该能够使用msbuild构建该解决方案(afaik该解决方案将首先使用Win32构建a,然后使用x86构建B)。

另一个选项是,您不应该从B引用项目A,而应该只添加引用A的输出dll。要做到这一点,首先要确保A.dll与B.exe位于同一目录中。然后通过浏览到输出目录并选择A.dll来添加对项目B的引用。还要将"复制本地"设置为false,因为那时不需要这样做。

对于这个问题,我看不到任何解决方法,除了删除A对本机x86 dll的依赖,将其替换为可以与之接口并编译为"AnyCPU"的东西(不确定您受什么dll/s的限制)。基本上,我的理解是,win32意味着它可以在比x86编译程序更多的处理器上运行,因此从MSbuild的角度来看,它们是不兼容的。如果为平台指定"AnyCPU",会发生什么情况?

刚刚发现了一种有趣的方法:使用一些自定义XML扩展.csproj文件,以便正确构建依赖的.vcxproj。

http://troyparsons.com/blog/2012/08/fixing-csproj-builds-that-reference-vcxproj-files-using-assignprojectconfiguration-task/#comment-843

为了防止链接失效,这里是重要的部分。不知道它为什么或如何工作,但它为我做了工作!

<Target Name="PrepProjectConfiguration" BeforeTargets="PrepareForBuild" Condition="'$(Platform)' == 'x86'">
   <AssignProjectConfiguration
         CurrentProjectConfiguration="$(Configuration)"
         CurrentProjectPlatform="$(Platform)"
         ProjectReferences="@(ProjectReference)"
         ResolveConfigurationPlatformUsingMappings="true">
      <Output TaskParameter="AssignedProjects" ItemName="ProjectReferenceWithConfiguration" />
   </AssignProjectConfiguration>
   <ItemGroup>
      <ProjectReference Remove="@(ProjectReferenceWithConfiguration)" />
   </ItemGroup>
   <Message Text="  regular reference %(ProjectReference.Identity)" />
   <Message Text="re-mapped reference %(ProjectReferenceWithConfiguration.Identity) - %(ProjectReferenceWithConfiguration.Configuration)|%(ProjectReferenceWithConfiguration.Platform)" />
</Target>