如何添加对C#项目调用的非托管C ++项目的引用?

时间:2011-02-24 16:45:16

标签: c# c++ visual-studio unmanaged

一种解决方案(the.sln)

一个C ++项目(2010年的mycppproject.vcxproj或2008年的mycppproject.vcproj),它编译导出某些函数的本机DLL。在调试中,这构建了c:\ output \ Debug \ mycppproject_d.dll,在发行版中,这构建了c:\ output \ Release \ mycppproject.dll。

包含PInvoke的一个C#控制台应用程序(mycsharpconsole.csproj)调用DLL。

所有编辑都很好。

当我构建时,我希望能够将csharp项目中的引用添加到cpp DLL项目中,以便它可以将相应的文件从相应的目录复制到\ bin \ Debug目录中构建csharp项目成。

这应该是可能的,因为IDE知道有关构建DLL的位置以及构建C#应用程序的位置的所有内容。

在Visual Studio 2010中:

我在csharp项目上尝试过“Dependencies ...”并在mycppproject上添加依赖项,但这没有效果。

我在csharp项目上尝试了“添加引用...”并添加了对cpp项目的引用,但是我收到一条警告消息“项目的目标框架版本”mycppproject“高于当前项目目标框架版本。您是否要将此引用添加到项目中? (是/否/取消)。

单击“是”会产生错误消息“无法添加对mycppproject的引用。”

4 个答案:

答案 0 :(得分:36)

您无法添加对非托管DLL的引用。

相反,您应该制作一个后期构建任务来复制文件。

或者,您可以将非托管DLL的链接添加为C#项目中的文件,并将Build Action设置为None,将Copy to Output Directory设置为Copy If Newer

答案 1 :(得分:18)

我会关注Slaks' second answer ...

[...]您可以在C#项目中添加非托管DLL的链接作为文件,并将“构建操作”设置为“无”并将“复制到输出目录”设置为“如果较新则复制”。

...后跟my comment,以区分Debug和Release版本(即使有点“hackish”,因为它需要您手动编辑C#项目文件)

用文本编辑器打开你的C#项目的csproj文件并搜索所有“YourNativeCppProject.dll”事件(没有“.dll”子命令,所以如果你也添加了pdb文件作为链接,你会发现不止一次出现),并使用宏更改Include路径,例如:Include =“$(SolutionDir)$(ConfigurationName)\ YourNativeCppProject.dll

PS:如果查看属性(F4),即使切换到Release配置,VS也会显示Debug的路径,但如果编译,则会看到复制到输出的dll是发行版本*

答案 2 :(得分:13)

Visual Studio不支持从托管C#one引用非托管C ++项目,但MSBuild支持引用任何其他项目中的任何项目。

您可以手动编辑.csproj文件,手动添加对项目的引用。在该文件中,找到您现有的ProjectReference元素集(如果您没有,则添加新的ItemGroup)并添加以下参考:

<ProjectReference Include="..\mycpproject.csproj">
  <Project>{b402782f-de0a-41fa-b364-60612a786fb2}</Project>
  <Name>mycppproject</Name>
  <ReferenceOutputAssembly>false</ReferenceOutputAssembly>
  <OutputItemType>Content</OutputItemType>
  <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</ProjectReference>

执行构建时,引用将导致MSBuild首先构建引用的项目。 ReferenceOutputAssembly值告诉MSBuild不要复制构建的输出程序集(因为C ++项目不生成一个),但OutputItemTypeCopyToOutputDirectory值指示它复制输出内容到引用项目的输出文件夹。

您将能够在Visual Studio中看到该引用,但您无法在那里做很多事情。

此答案基于Kirill Osenkov在其MSDN博客上解决的类似问题:https://blogs.msdn.microsoft.com/kirillosenkov/2015/04/04/how-to-have-a-project-reference-without-referencing-the-actual-binary/

答案 3 :(得分:2)

Add Rederences仅适用于.NET程序集,.net项目在同一解决方案中或适用于COM组件(无论如何都将为其创建管理器包装器......)。

在您的C#代码中,使用DLLImport 访问C ++ dll不会意味着Visual Studio将知道应该从哪里复制外部dll。

想象一下,DLLImport是一个运行时选项,你在其中使用的路径在运行时用于查找dll,因此你必须自己部署c ++ dll并使其可用于.net应用程序,通常在同一个应用程序中bin文件夹。