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

时间:2022-10-16 07:20:49

One solution (the.sln)

一个解决方案(the.sln)

One C++ project (mycppproject.vcxproj in 2010or mycppproject.vcproj in 2008) which compiles a native DLL exporting some function(s). In debug this builds c:\output\Debug\mycppproject_d.dll and in release this builds c:\output\Release\mycppproject.dll.

一个c++项目(mycppproject。在2010年或mycppproject vcxproj。vcproj在2008年)编译一个本地DLL输出一些函数。在调试中,这将构建c:\输出\调试\mycppproject_d。在发布版本中,这将构建c:\输出\发布\mycppproject.dll。

One C# console application (mycsharpconsole.csproj) containing PInvoke calls into the DLL.

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

All compiles fine.

一切运行良好。

When I build, I would like to be able to add a reference from the csharp project to the cpp DLL project so that it can copy the appropriate file from the appropriate directory into the \bin\Debug directory the csharp project is built into.

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

This should be possible, since the IDE knows everything there is to know about where the DLL gets built, and where the C# application gets built.

这应该是可能的,因为IDE知道关于DLL在哪里构建,以及c#应用程序在哪里构建的所有信息。

In Visual Studio 2010:

在Visual Studio 2010中:

I've tried "Dependencies..." on the csharp project and adding a dependency on mycppproject, but that has no effect.

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

I've tried "Add Reference..." on the csharp project and adding a reference to the cpp project, but I get a warning message 'The Target Framework version for the project "mycppproject" is higher than the current project Target Framework version. Would you like to add this reference to your project anyway?' (Yes/No/Cancel).

我在csharp项目上尝试过“添加引用……”,并添加了对cpp项目的引用,但是我得到了一个警告消息:“项目“mycppproject”的目标框架版本高于当前的项目目标框架版本。”无论如何,你想把这个参考加入到你的项目中吗?”(Yes / No /取消)。

Clicking "Yes" produces the error message "A reference to mycppproject" could not be added."

点击“Yes”会产生错误信息,不能添加“对mycppproject的引用”。

4 个解决方案

#1


9  

Visual Studio doesn't support referencing an unmanaged C++ project from a managed C# one, but MSBuild supports referencing any project from any other project.

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

You can manually add a reference to your project by editing the .csproj file by hand. In the file, find your existing set of ProjectReference elements (or add a new ItemGroup if you don't have one) and add the following reference:

通过手工编辑.csproj文件,可以手动向项目添加引用。在该文件中,找到您现有的项目重构元素集(如果没有的话,可以添加一个新的项目组),并添加以下引用:

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

When you perform the build, the reference will cause MSBuild to build the referenced project first. The ReferenceOutputAssembly value tells MSBuild not to copy the output assembly of the build (since the C++ project does not produce one), but the OutputItemType and CopyToOutputDirectory values instruct it to copy the output content to the referencing project's output folder.

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

You will be able to see the reference in Visual Studio, but you can't do much with it there.

你可以在Visual Studio中看到这个引用,但是你不能在那里做太多的事情。

This answer is based on a similar problem solved by Kirill Osenkov on his MSDN blog: https://blogs.msdn.microsoft.com/kirillosenkov/2015/04/04/how-to-have-a-project-reference-without-referencing-the-actual-binary/

这个答案基于Kirill Osenkov在他的MSDN博客上解决的类似问题:https://blogs.msdn.microsoft.com/kirillosenkov/2015/04/04/04/04/04/howto -a- projectrefering-- the-actual-binary/。

#2


33  

You cannot add a reference to an unmanaged DLL.

不能向非托管DLL添加引用。

Instead, you should make a post-build task to copy the file.

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

Alternatively, you can add a link to the unmanaged DLL as a file in the C# project, and set Build Action to None and Copy to Output Directory to Copy If Newer.

或者,您可以在c#项目中作为文件添加到非托管DLL的链接,并将Build动作设置为None,如果更新,则复制到输出目录。

#3


18  

I would follow Slaks' second answer...

我会遵循Slaks的第二种回答……

[...] you can add a link to the unmanaged DLL as a file in the C# project, and set Build Action to None and Copy to Output Directory to Copy If Newer.

[…您可以将链接添加到c#项目中的非托管DLL作为文件,并将Build动作设置为None,如果更新,则复制到输出目录。

... followed by my comment, to differentiate between Debug and Release builds (even if is a little bit "hackish", since it requires you to manually edit the C# project file)

…接下来是我的评论,以区分调试和发布构建(即使有点“hackish”,因为它要求您手动编辑c#项目文件)

open your C# project's csproj file with a text editor and search for all "YourNativeCppProject.dll" occurrences (without the ".dll" subfix, so if you added pdb files as a link too, you'll find more than one occurrence), and change the Include path using macros, for example: Include="$(SolutionDir)$(ConfigurationName)\YourNativeCppProject.dll

使用文本编辑器打开c#项目的csproj文件,并搜索“YourNativeCppProject”。dll“发生(没有”)。dll“subfix,所以如果您也将pdb文件作为链接添加进来,您将发现不止一个事件),并使用宏更改包含路径,例如:Include=“$(SolutionDir)$(ConfigurationName)\ yournatippproject .dll。

PS: if you look at the properties (F4), VS shows you the Debug's path even if you switch to the Release configuration, but if you compile, you'll see that the dll copied to output is the release version*

PS:如果您查看属性(F4), VS显示了调试的路径,即使您切换到发布配置,但是如果您编译,您将看到复制到输出的dll是发布版本*

#4


2  

Add Rederences only works for .NET assemblies, .net projects in the same solution or for COM components ( for which a manager wrapper will be created anyway... ).

添加Rederences仅适用于.net程序集、.net项目中相同的解决方案或COM组件(无论如何,将为其创建一个管理器包装器…)。

the fact that in your C# code you access the C++ dll with DLLImport does not mean that Visual Studio will know from where to where the external dll should be copied.

在您的c#代码中,您使用DLLImport访问c++ dll,这并不意味着Visual Studio将知道从何处复制外部dll。

Imagine that DLLImport is a runtime option, the path you puth in there is used at runtime to look for the dll, so you have to deploy the c++ dll yourself and make it available for the .net application, usually in the same bin folder.

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

#1


9  

Visual Studio doesn't support referencing an unmanaged C++ project from a managed C# one, but MSBuild supports referencing any project from any other project.

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

You can manually add a reference to your project by editing the .csproj file by hand. In the file, find your existing set of ProjectReference elements (or add a new ItemGroup if you don't have one) and add the following reference:

通过手工编辑.csproj文件,可以手动向项目添加引用。在该文件中,找到您现有的项目重构元素集(如果没有的话,可以添加一个新的项目组),并添加以下引用:

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

When you perform the build, the reference will cause MSBuild to build the referenced project first. The ReferenceOutputAssembly value tells MSBuild not to copy the output assembly of the build (since the C++ project does not produce one), but the OutputItemType and CopyToOutputDirectory values instruct it to copy the output content to the referencing project's output folder.

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

You will be able to see the reference in Visual Studio, but you can't do much with it there.

你可以在Visual Studio中看到这个引用,但是你不能在那里做太多的事情。

This answer is based on a similar problem solved by Kirill Osenkov on his MSDN blog: https://blogs.msdn.microsoft.com/kirillosenkov/2015/04/04/how-to-have-a-project-reference-without-referencing-the-actual-binary/

这个答案基于Kirill Osenkov在他的MSDN博客上解决的类似问题:https://blogs.msdn.microsoft.com/kirillosenkov/2015/04/04/04/04/04/howto -a- projectrefering-- the-actual-binary/。

#2


33  

You cannot add a reference to an unmanaged DLL.

不能向非托管DLL添加引用。

Instead, you should make a post-build task to copy the file.

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

Alternatively, you can add a link to the unmanaged DLL as a file in the C# project, and set Build Action to None and Copy to Output Directory to Copy If Newer.

或者,您可以在c#项目中作为文件添加到非托管DLL的链接,并将Build动作设置为None,如果更新,则复制到输出目录。

#3


18  

I would follow Slaks' second answer...

我会遵循Slaks的第二种回答……

[...] you can add a link to the unmanaged DLL as a file in the C# project, and set Build Action to None and Copy to Output Directory to Copy If Newer.

[…您可以将链接添加到c#项目中的非托管DLL作为文件,并将Build动作设置为None,如果更新,则复制到输出目录。

... followed by my comment, to differentiate between Debug and Release builds (even if is a little bit "hackish", since it requires you to manually edit the C# project file)

…接下来是我的评论,以区分调试和发布构建(即使有点“hackish”,因为它要求您手动编辑c#项目文件)

open your C# project's csproj file with a text editor and search for all "YourNativeCppProject.dll" occurrences (without the ".dll" subfix, so if you added pdb files as a link too, you'll find more than one occurrence), and change the Include path using macros, for example: Include="$(SolutionDir)$(ConfigurationName)\YourNativeCppProject.dll

使用文本编辑器打开c#项目的csproj文件,并搜索“YourNativeCppProject”。dll“发生(没有”)。dll“subfix,所以如果您也将pdb文件作为链接添加进来,您将发现不止一个事件),并使用宏更改包含路径,例如:Include=“$(SolutionDir)$(ConfigurationName)\ yournatippproject .dll。

PS: if you look at the properties (F4), VS shows you the Debug's path even if you switch to the Release configuration, but if you compile, you'll see that the dll copied to output is the release version*

PS:如果您查看属性(F4), VS显示了调试的路径,即使您切换到发布配置,但是如果您编译,您将看到复制到输出的dll是发布版本*

#4


2  

Add Rederences only works for .NET assemblies, .net projects in the same solution or for COM components ( for which a manager wrapper will be created anyway... ).

添加Rederences仅适用于.net程序集、.net项目中相同的解决方案或COM组件(无论如何,将为其创建一个管理器包装器…)。

the fact that in your C# code you access the C++ dll with DLLImport does not mean that Visual Studio will know from where to where the external dll should be copied.

在您的c#代码中,您使用DLLImport访问c++ dll,这并不意味着Visual Studio将知道从何处复制外部dll。

Imagine that DLLImport is a runtime option, the path you puth in there is used at runtime to look for the dll, so you have to deploy the c++ dll yourself and make it available for the .net application, usually in the same bin folder.

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