C++/CLI在.Net Core中的支持

33

我们的项目结构如下:

native.dll :这包含了用C/C++编写的纯本机代码。此native.dll使用*def文件暴露一些函数。

包装库(wrapper.dll 使用.NET Framework v4.0编译):为了使用native.dll的功能,使用C++\CLI编写了一个包装库(wrapper.dll),其中包含所有互操作性封送处理代码。

应用程序(Console App v4.0)直接使用wrapper.dll来使用native.dll提供的功能。

现在,这个项目需要在.Net Core中运行。这意味着我们将有一个引用了wrapper.dll.Net Core应用程序,而wrapper.dll又引用了native.dll

我知道这不会直接起作用。但问题是.Net Core(CoreCLR)是否支持C++\CLI(clr\oldsyntax)运行时环境?

如果不支持,那么这个应用程序可能的解决方案是什么?


@HansPassant:你说“实际上有很少的平台目标可以执行本机代码”,能否详细说明一下?你真的是指目前没有办法在 .Net Core 下运行这些类型的项目吗? - User1234
@HansPassant:谢谢你。是的,你说得对,我们选择了 .Net Core,因为我们想在 Linux 上运行我们的 dotnet 代码(wrapper.dll,它又调用 native.dll)。但正如你所说,目前 CoreCLR 不支持 C++/CLI 运行时,因此所有这些似乎都不可行。我实际上已经阅读了很多关于 .Net Core 的 MSDN 博客,但其中没有一个暗示我可以在 .Net Core 中集成 C++\CLI。那么 .Net Core 团队将来是否真的会支持这一点呢? - User1234
2
有许多情况下,C++/CLI对.NET Core的支持将非常有用。例如,如果您正在使用跨平台的C++代码,并希望将其与.Net业务层进行接口,以便更快地开发。我非常惊讶微软没有提供这个功能 - 它似乎是理想的。 - Zesty
3
@hanspassant,这个说法有点简单化了。如果那个DLL碰巧是一个可以编译成Linux和macOS平台的跨平台库呢?这种用例显然存在,使用C++/CLI支持它们会很好。 - Per Lundberg
1
我也有同样的需求,而且很惊讶它还没有得到支持。 - Weipeng
5个回答

11

4
但是其他选择都无法与C++/CLI所提供的优雅相媲美。 - Weipeng
3
.NET Core 3.1将支持在Windows上使用C++/CLI。 - markf78
2
@markf78 你知道这是否意味着我们可以在.NET Core应用程序中运行现有的C++/CLI程序集而无需重新编译它们吗? - Cocowalla
1
@Cocowalla 我只知道在这里发布的内容:https://devblogs.microsoft.com/cppblog/the-future-of-cpp-cli-and-dotnet-core-3/ - markf78
1
@markf78,微软的某个人刚刚说了“不”: https://github.com/dotnet/coreclr/issues/18013#issuecomment-549880929 :`( - Cocowalla
这会改变什么吗?:https://devblogs.microsoft.com/cppblog/an-update-on-cpp-cli-and-dotnet-core/ - knocte

9

最终官方终于宣布了... (下一个愿望...支持Linux@ .Net 5 ^^)

https://devblogs.microsoft.com/cppblog/the-future-of-cpp-cli-and-dotnet-core-3/

C++/CLI将获得完整的IDE支持,以便面向.NET Core 3.1及更高版本。此支持包括在Windows上进行项目、智能感知和混合模式调试(IJW)。我们目前没有计划为C++/CLI针对macOS或Linux进行开发。另外,“/clr:纯净”和“/clr:安全”的编译不会支持.NET Core。

第一个C++/CLI的公共预览版即将问世。Visual Studio 2019 16.4 Preview 1已经包含了一个带有“/clr: netcore”的更新后的编译器。


更新:来自原始网址的回复: “我们仍在努力完成IDE和MSBuild集成,因此我目前无法分享示例项目。一旦可用,可能是与16.4 Preview 2或3一起发布。”

(16.4 Preview1无法创建C++/CLI与.NetCore项目。)


191015 发布了16.4 Preview2。 我尝试过使用c++/CLI dll作为asp.net core 3.1,它可以工作。 (需要将平台设置为x64,同时也是asp.net core和c++/CLI dll)


+VS2019 16.4 预览版2,.NetCore 3.1 预览版1 已发布

https://github.com/dotnet/coreclr/issues/18013#issuecomment-542521040 (新增“CLR 类库 (.NetCore)”、“针对 .Net Core 的 C++ 库目标”)

https://github.com/dotnet/coreclr/issues/18013#issuecomment-542570482 (预览版中存在一些已知问题。)
- wade.ec
1
您可以在没有VS预览的情况下使其工作。右键单击要管理的类,然后转到“属性” - “C / C ++” - “代码生成”。禁用“最小重建”,禁用C ++异常,将基本运行时检查设置为默认值。 转到“预编译头”,将其设置为“不使用...” 转到“命令行”,添加“/clr /fu * pathtomscorlib *。 例如,“/clr /FU“C:\ Program Files(x86)\ dotnet \ shared \ Microsoft.NETCore.App \ 3.1.0-preview1.19506.1 \ mscorlib.dll”“。 - mitchellJ
我仍需要安装 .net core 3.1-preview1,并且我可以在没有预览的情况下使用VS 2019 16.3.x,对吗?因为需要“3.1.0-preview1.19506.1 \ mscorlib.dll”。 - wade.ec
1
是的,您需要 .NET Core 预览版,但不需要 VS 预览版。https://dotnet.microsoft.com/download/dotnet-core/3.1 - mitchellJ
@wade.ec 你知道我们是否可以在.NET Core应用程序中运行旧的、现有的C++/CLI程序集而无需重新编译它们吗? - Cocowalla
@Cocowalla 我不知道。 将会有一份关于c++/cli net core的文档,但自06/28以来仍未更新 https://github.com/dotnet/docs/issues/13152 - wade.ec

8

.net Core团队现在只承诺支持C++/CLI仅限于Windows系统。

最初的意图是在.net Core 3.0中提供此功能。虽然我还没有在发布说明中找到明确的提及,但是支持C++/CLI是WPF(仅限于Windows)的先决条件,WPF现在已经在.net Core 3.0中得到了支持。

在Windows上支持混合模式程序集 - #18013

这个问题(#18013)将追踪与在CoreCLR上加载和运行混合模式程序集相关的进展情况。主要目标是为WPF和其他现有的C++/CLI代码在.NET Core上提供支持。其中一些工作将依赖于MSVC编译器的更新。

上面由@Tomas-Kubes提到的GitHub问题(#659),核心CLR是否支持C++/CLI跨平台?- #659,是关于跨平台的C++/CLI的。

顺便说一句,在VS2017/.net-4.7中,我正在“clr\oldsyntax”上收到编译器警告。因此,此编译器标志已被弃用。

更新:这将在.Net Core 3.1中实现


关于你的更新,实际上是这样的:https://devblogs.microsoft.com/cppblog/an-update-on-cpp-cli-and-dotnet-core/ 但它是否跨平台? - knocte

4

如果你想使用C++(即向.NET公开一个面向对象接口)并且坚持不用其他语言的话,另一种潜在的解决方案是查看来自mono项目的CppSharp。它能够通过自动生成的C#包装器公开本地C++代码。它支持Windows、Linux以及OSX。但是,我不知道生成的代码能否编译为.NET标准目标(没有尝试过)。我只能猜测应该可以,因为生成的代码不使用任何高级API(基本上是interop和marshalling代码);另外,还可以定制生成过程(虽然可能不是一件容易的事情)。


5
或者尝试使用SWIG(http://www.swig.org/)。SWIG是一种工具,可将用C和C++编写的程序与多种高级编程语言(包括C#)连接起来。 - Sonic78

4

对于那些想了解一般的.Net Core内容而没有特定clr参数的人(因为这在谷歌上是高排名),Microsoft编写了一份指南,介绍如何将C++/CLI移植到.Net Core:

https://learn.microsoft.com/en-us/dotnet/core/porting/cpp-cli


将C++/CLI项目移植

要将C++/CLI项目移植到.NET Core,请对.vcxproj文件进行以下更改。这些迁移步骤与其他项目类型所需的步骤不同,因为C++/CLI项目不使用SDK样式的项目文件。

  1. <CLRSupport>true</CLRSupport>属性替换为<CLRSupport>NetCore</CLRSupport>。此属性通常在特定于配置的属性组中,因此您可能需要在多个位置替换它。
  2. <TargetFrameworkVersion>属性替换为<TargetFramework>netcoreapp3.1</TargetFramework>
  3. 删除任何.NET Framework引用(例如<Reference Include="System" />)。使用<CLRSupport>NetCore</CLRSupport>时,会自动引用.NET Core SDK程序集。
  4. 根据需要更新.cpp文件中的API使用情况,以删除.NET Core不支持的API。因为C++/CLI项目往往是相当薄的互操作层,所以通常不需要进行太多更改。您可以使用.NET可移植性分析器来识别C++/CLI二进制文件中使用的不受支持的.NET API,就像纯管理二进制文件一样。

无需使用MSBuild构建

也可以在不使用MSBuild的情况下构建C++/CLI项目。按照以下步骤直接使用cl.exe和link.exe构建.NET Core的C++/CLI项目:

  1. 在编译时,向cl.exe传递-clr:netcore
  2. 引用必要的.NET Core参考程序集。在链接时,将.NET Core应用程序主机目录提供为LibPath(以便可以找到ijwhost.lib)。
  3. 将ijwhost.dll(来自.NET Core应用程序主机目录)复制到项目的输出目录中。
  4. 确保第一个运行托管代码的组件存在runtimeconfig.json文件。如果应用程序具有托管入口点,则会自动创建并复制runtime.config文件。但是,如果应用程序具有本机入口点,则需要为第一个C++/CLI库创建runtimeconfig.json文件,以便使用.NET Core运行时。

还有一些细微之处,但这些是移植的实际步骤。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接