英文:
Changing .NET framework 4.7.2 to .NET Core 6.0 for a C++/CLI project
问题
I have a Visual Studio C++/CLI project which contains some Google unit tests, and the configuration type of the project is Application
(an executable). I am trying to build the project by changing from .NET framework 4.7.2 to .NET Core 6.0 by following the steps here: https://learn.microsoft.com/en-us/dotnet/core/porting/cpp-cli.
But I am getting the following error: C++/CLI projects targeting .NET Core must be dynamic libraries.
Upon looking at the corresponding SDK file which throws the error:
<NETSdkError Condition="('$(Language)' == 'C++' and '$(_EnablePackageReferencesInVCProjects)' != 'true') and $(OutputType) != 'library' and '$(TargetFrameworkIdentifier)' == '.NETCoreApp'" ResourceName="NoSupportCppNonDynamicLibraryDotnetCore" />
It seems .NET Core does not support C++/CLI executables:
- https://developercommunity.visualstudio.com/t/support-for-ccli-exe-projects-with-net-56-as-with/1488200
- https://github.com/dotnet/docs/issues/33536
Upon searching I can think of two ways around this
-
Change the project to procduce a dynamic library (dll) instead of an executable. Expose a method from the dll to run all the tests. Create another C++ native/C# executable project which references this dll and runs the method. This method is along the lines of the post from here: https://stackoverflow.com/questions/34943517/dynamic-dll-load-and-googletest.
-
Re-write all the tests in C# or some other unit test framework in C++/CLI.
Is there some other way with minimal changes? What is recommended?
英文:
I have a Visual Studio C++/CLI project which contains some Google unit tests, and the configuration type of the project is Application
(an executable). I am trying to build the project by changing from .NET framework 4.7.2 to .NET Core 6.0 by following the steps here: https://learn.microsoft.com/en-us/dotnet/core/porting/cpp-cli.
But I am getting the following error: C++/CLI projects targeting .NET Core must be dynamic libraries.
Upon looking at the corresponding SDK file which throws the error:
<NETSdkError Condition="('$(Language)' == 'C++' and '$(_EnablePackageReferencesInVCProjects)' != 'true') and $(OutputType) != 'library' and '$(TargetFrameworkIdentifier)' == '.NETCoreApp'"
ResourceName="NoSupportCppNonDynamicLibraryDotnetCore" />
It seems .NET Core does not support C++/CLI executables:
- https://developercommunity.visualstudio.com/t/support-for-ccli-exe-projects-with-net-56-as-with/1488200
- https://github.com/dotnet/docs/issues/33536
Upon searching I can think of two ways around this
-
Change the project to procduce a dynamic library (dll) instead of an executable. Expose a method from the dll to run all the tests. Create another C++ native/C# executable project which references this dll and runs the method. This method is along the lines of the post from here: https://stackoverflow.com/questions/34943517/dynamic-dll-load-and-googletest.
-
Re-write all the tests in C# or some other unit test framework in C++/CLI.
Is there some other way with minimal changes? What is recommended?
答案1
得分: 1
DLL是托管C++/CLI代码的最佳实践方式。
这个问题实际上是一个非常相似问题的重复:https://stackoverflow.com/questions/75957230/is-it-possible-to-create-a-c-console-app-using-the-dotnet-cli#:~:text=C%2B%2B%2FCLI%20is%20still%20supported%20with%20VS2022%20%28both%20with.NET,wrapper%20libraries%20between%20native%20libraries%20and%20C%23%20applications.
英文:
DLL is best practice way of hosting C++/CLI code.
This question is actually a duplication of very similar question: https://stackoverflow.com/questions/75957230/is-it-possible-to-create-a-c-console-app-using-the-dotnet-cli#:~:text=C%2B%2B%2FCLI%20is%20still%20supported%20with%20VS2022%20%28both%20with.NET,wrapper%20libraries%20between%20native%20libraries%20and%20C%23%20applications.
答案2
得分: 0
你绝对需要更改以输出一个库(DLL),就像错误提示你的那样。然后,如何处理单元测试就由你决定了。我会从创建一个包装的命令行项目开始,只需将参数传递给DLL入口点。然后,我会在自己的时间里重写MSTest中的测试。
根据Microsoft的Mike Rousos所说:
将vcxproj迁移到.NET Core
现在是有趣的部分 - 更新示例应用程序以在.NET Core上运行。所需的更改实际上非常小。如果以前已将C#项目迁移到.NET Core,那么迁移C++/CLI项目会更简单,因为项目文件格式不会更改。对于托管项目,.NET Core和.NET Standard项目使用新的SDK样式项目文件格式。然而,对于C++/CLI项目,同样的vcxproj格式用于针对.NET Core和.NET Framework。
需要的只是对项目文件进行一些更改。其中一些可以通过Visual Studio IDE完成,但其他一些(例如添加WinForms引用)目前还不能完成。因此,目前更新项目文件的最简单方法是卸载VS中的项目并直接编辑vcxproj,或者使用像VS Code或Notepad这样的编辑器。
将 <CLRSupport>true</CLRSupport>
替换为 <CLRSupport>NetCore</CLRSupport>
。这告诉编译器在构建时使用 /clr:netcore
而不是 /clr
。
这个更改可以通过Visual Studio的项目配置界面进行。请注意,<CLRSupport>
在示例项目的项目文件中的每个配置/平台特定的属性组中分别指定,因此需要在四个不同的地方进行更新。
将 .NET Framework
引用(System、System.Data、System.Windows.Forms和System.Xml)替换为来自Windows桌面.NET Core SDK的WinForms组件的以下引用。此步骤目前没有Visual Studio IDE支持,因此必须通过直接编辑vcxproj来完成。请注意,只需要引用Windows桌面SDK,因为.NET Core SDK(其中包括System、System.Xml等库)会自动包含。在迁移文档中有适用于WinForms、WPF或两者都有的不同Framework引用。
<FrameworkReference Include="Microsoft.WindowsDesktop.App.WindowsForms" />
做出这些更改后,C++/CLI项目将成功构建并针对.NET Core进行目标。如果使用的是Visual Studio 2019的最新版本(16.5或16.6预览1),在运行时一切应该正常工作,迁移完成!
在Visual Studio 2019 16.5预览2之前,C++/CLI库不会生成必要的.runtimeconfig.json文件,以指示C++/CLI库使用的.NET Core版本,因此必须手动添加。因此,如果使用的是较旧版本的Visual Studio,您需要手动创建此CppCliInterop.runtimeconfig.json
文件,并确保将其复制到输出目录:
{
"runtimeOptions": {
"tfm": "netcoreapp6.0",
"framework": {
"name": "Microsoft.WindowsDesktop.App",
"version": "6.0.3"
}
}
}
现在应用程序可以在.NET Core上运行了!
1: https://devblogs.microsoft.com/cppblog/porting-a-c-cli-project-to-net-core/
英文:
You absolutely need to change to output a library (DLL), just like the error tells you to. Then it's up to you how you want to handle unit testing. I would start by making a wrapper command line project that just passes arguments to the DLL entry point. Then I would rewrite the tests in MSTest at my leisure.
According to Mike Rousos at Microsoft:
Migrating a vcxproj to .NET Core
Now for the interesting part – updating the sample app to run on .NET Core. The changes needed are actually quite minimal. If you’ve migrated C# projects to .NET Core before, migrating C++/CLI projects is even simpler because the project file format doesn’t change. With managed projects, .NET Core and .NET Standard projects use the new SDK-style project file format. For C++/CLI projects, though, the same vcxproj format is used to target .NET Core as .NET Framework.
All that’s needed is to make a few changes to the project file. Some of these can be done through the Visual Studio IDE, but others (such as adding WinForms references) can’t be yet. So the easiest way to update the project file, currently, is to just unload the project in VS and edit the vcxproj directly or to use an editor like VS Code or Notepad.
Replace <CLRSupport>true</CLRSupport>
with <CLRSupport>NetCore</CLRSupport>
. This tells the compiler to use /clr:netcore
instead of /clr
when building.
This change can be done through Visual Studio’s project configuration interface if you prefer.
Note that <CLRSupport>
is specified separately in each configuration/platform-specific property group in the sample project’s project file, so the update needs to be made four different places.
Replace <TargetFrameworkVersion>4.7.2</TargetFrameworkVersion>
with <TargetFramework>netcoreapp6.0</TargetFramework>
.
These settings can be modified through Visual Studio’s project configuration interface in the ‘Advanced’ tab. Note, however, that changing a project’s CLR support setting as described in the previous step won’t change <TargetFrameworkVersion> automatically, so be sure to clear the “.NET Target Framework Version” setting before selecting .NET Core Runtime Support.
Replace .NET Framework references (to System, System.Data, System.Windows.Forms, and System.Xml) with the following reference to WinForms components from the Windows Desktop .NET Core SDK. This step doesn’t have Visual Studio IDE support yet, so it must be done by editing the vcxproj directly. Notice that only a reference to the Windows Desktop SDK is needed because the .NET Core SDK (which includes libraries like System, System.Xml, etc.) is included automatically. There are different Framework references for WinForms, WPF, or both (as explained in the migration docs).
<FrameworkReference Include="Microsoft.WindowsDesktop.App.WindowsForms" />
With those changes made, the C++/CLI project will build successfully targeting .NET Core. If you’re using the latest version of Visual Studio 2019 (16.5 or 16.6 preview 1), everything should work at runtime, too, and the migration is done!
Prior to Visual Studio 2019 16.5 preview 2, C++/CLI libraries didn’t generate the .runtimeconfig.json file necessary for C++/CLI libraries to indicate which version of .NET Core they use, so it had to be added manually. So, if you’re using an older version of Visual Studio, you’ll need to create this CppCliInterop.runtimeconfig.json
file manually and make sure it’s copied to the output directory:
{
"runtimeOptions": {
"tfm": "netcoreapp6.0",
"framework": {
"name": "Microsoft.WindowsDesktop.App",
"version": "6.0.3"
}
}
}
The app can now run on .NET Core!
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论