我目前有一个 VS2022 解决方案,其中包括一个构建本机 DLL 的完全本机 VC++ 项目,该项目依赖于许多通过 VCPKG 管理和版本控制的 C++ 库。
然后,.NET Framework 4.8(非 SDK)WPF 应用程序使用本机 DLL,该应用程序使用 P/Invoke 调用非托管 DLL 公开的 C 风格 API。 (无法将此应用程序升级到 .NET 5+,因为它还依赖于第三方 .NET 4.8 SDK,而我离不开它。)
在新机器上构建这个解决方案有点痛苦,因为设置 VCPKG 需要遵循一页长的自述文件安装步骤,并构建我的小型 288 KB DLL(加上其 12 MB 的真正二进制依赖项),从而间接下载并构建 15.5 GB 的 VCPKG 源依赖项和中间对象(主要是 Boost)。显然,其中绝大多数并未被最终产品实际使用,但仍然需要构建。庞大的依赖项金字塔需要近一个小时才能在新机器上下载和构建,但是一旦构建了它的依赖项,编译 my C++ 代码最多只需要几秒钟。
由于我的 .NET WPF 项目运行需要本机程序集,因此它在 VS 解决方案中配置为项目依赖项。因此,在新机器上,直到 VC++ 项目构建完成后,.NET 项目才会构建。我想我可以将 VC++ 项目的二进制输出检查到 Git 存储库中,但这本身似乎是一种相当恶臭的代码味道。
我认为构建一次 C++ 项目并将结果发布为可供 .NET 项目使用的包,而不是作为直接 DLL 引用是有意义的。我假设 NuGet 是执行此操作的正确工具?我将在公司的内部 NuGet 源上发布构建的 NuGet 包,并将 WPF 应用程序更改为依赖于该包,而不是直接依赖于 VC++ 项目。这样,VC++ 项目的发布版本就可以正确管理,而不仅仅是将随机的
Bin
文件夹提交到我的 Git 存储库。
本机 NuGet 包的 MS 文档似乎面向使用 NuGet 来管理由其他本机项目使用的本机二进制依赖项。 主要 NuGet 文档更关心打包托管依赖项以供托管代码使用。
所以我的问题是:
是的,NuGet 可以成为对托管项目进行版本控制和分发本机代码二进制文件的合适工具,尤其是在处理 P/Invoke 时。要创建用于 P/Invoke 使用的本机 NuGet 包,您需要在包中包含本机 DLL 和任何依赖项,并指定适当的目标体系结构(例如 x86、x64)。您还可以包含 .targets 文件以确保 DLL 被复制到输出目录。这样,您的 WPF 应用程序就可以通过包使用本机 DLL,而无需直接项目依赖项。