我们如何在 c++/cli 项目中使用托管的 nuget 包

Posted

技术标签:

【中文标题】我们如何在 c++/cli 项目中使用托管的 nuget 包【英文标题】:How can we use managed nuget packages in c++/cli project 【发布时间】:2022-01-19 00:17:49 【问题描述】:

我想在 c++/cli 项目中使用托管 nuget 包。有没有办法做到这一点?

比如我的场景差不多是这样的:

我创建了一个 C# 项目(MainProject)并将 EntityFramework nuget 包添加到该项目中。

我又创建了一个 C# 项目 (TestCSProject) 并添加了 MainProject 作为对该项目的引用。然后在references中自动添加entityframework

我创建了一个 C++/CLI 项目 (TestCLIProject) 并添加了 MainProject 作为对该项目的引用,以便我想看看我是否可以使用实体框架。

但这并没有发生。

所以我想知道如何在 c++/cli 项目中使用托管 nuget 包

【问题讨论】:

是的,我在我的 C++/CLI 项目中添加了 using namespace System::Data::Entity(Presented in EntityFraneowrk.dll)。它显示错误,说它不存在。 Nuget 不支持 C++/CLI 项目,C++ 项目的包管理器是 vcpkg。不要打扰。您可以使用的一个技巧是向解决方案添加一个虚拟 C# 项目并使用其 Nuget 支持来获取库。您所做的,确保构建 C# 项目,以便您可以使用 Project > Add Reference > Browse 选择库。 意味着将 Nuget 包添加到虚拟 c# 项目,然后手动添加对 c++/cli 项目的所有引用?如果 nuget 包依赖于更多的 nuget 包并且如果我们有这么多的 dll 可以参考,那将会很麻烦? @HansPassant 它是C++,如果它不笨重,那么每个人都会使用它。请记住,C++/CLI 的主要目的是使与本机代码的互操作变得容易,这与使用数据库做任何事情相距一百万英里。将非互操作相关的代码移入 C# 库是明智之举。 这里我以EntityFramework为例。我的 C++/CLI 与任何数据库操作无关。在 C++/CLI 项目中,我需要使用托管 nuget 包中的程序集中存在的类 【参考方案1】:

C++/CLI 项目可以通过 packages.config 使用 nuget 包(在 VS2019 中仍然没有对 C++ 的 PackageReference 支持,PackageReference for NuGet packages in C++ projects)。正如 cmets 中所指出的,C++/CLI 应该仅用于与本机代码的互操作。无论如何,有时可能需要在这里使用 nuget 包。

在 Visual Studio 2019 中,以下内容适用于引用 .Net Framework 的 C++ 项目:

    转到包管理器控制台:Tools -> NuGet Package Manager -> Package Manager Console。然后安装 nuget 包 (instruction from Microsoft)。例如。 EF nuget 安装可能是这样的:

Install-Package EntityFramework -Version 6.4.4 -ProjectName TestCLIProject

安装 nuget 后,将在项目文件夹中创建一个 packages.config 文件并将其添加到项目中。例如。 EF nuget 安装 packages.config 后可能是这样的:

<?xml version="1.0" encoding="utf-8"?>
<packages>
    <package id="EntityFramework" version="6.4.4" targetFramework="native" />
</packages>
    从 nuget 添加对 dll 的引用。 Project -> Add Reference... -> Browse... -> 找到解决方案的文件夹 -> 转到 packages 文件夹 -> 转到 nuget 的文件夹 -> 找到 dll(s)

例如对于 EF,这导致 .vcxproj 更新为:

  <Reference Include="EntityFramework">
    <HintPath>..\packages\EntityFramework.6.4.4\lib\net45\EntityFramework.dll</HintPath>
  </Reference>
  <Reference Include="EntityFramework.SqlServer">
    <HintPath>..\packages\EntityFramework.6.4.4\lib\net45\EntityFramework.SqlServer.dll</HintPath>
  </Reference>
    项目已准备好构建。如果 Visual Studio 已选择退出 Tools -> Options -> NuGet Package Manager -> Automatically check for missing packages during build in Visual Studio,则可以手动恢复 nugets,例如在包管理器控制台中使用Update-Package 命令。

【讨论】:

以上是关于我们如何在 c++/cli 项目中使用托管的 nuget 包的主要内容,如果未能解决你的问题,请参考以下文章

如何从我的 C++/CLI 代码进入非托管 C++ 库

如何使用 C++/CLI Wrapper 将变量参数从托管传递到非托管?

C# 使用 CLI 包装器调用非托管 C++

C++/CLI + C++ Native 会提高性能吗? [关闭]

将非托管方法作为回调传递给托管 C++/CLI 类

(C++/CLI) 如何在 C++ CLI 中获取从本机代码到托管代码的回调?