Skip to content

Commit f3e288a

Browse files
adegeogewarren
andauthored
Add some clarifications around C++/CLI projects (#39228)
* Update article * Apply suggestions from code review Co-authored-by: Genevieve Warren <24882762+gewarren@users.noreply.github.com> * minor --------- Co-authored-by: Genevieve Warren <24882762+gewarren@users.noreply.github.com>
1 parent 39b6ea1 commit f3e288a

File tree

1 file changed

+46
-41
lines changed

1 file changed

+46
-41
lines changed

docs/core/porting/cpp-cli.md

Lines changed: 46 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -1,52 +1,57 @@
11
---
2-
title: Migrate C++/CLI projects to .NET Core and .NET 5+
3-
description: Learn about porting C++/CLI projects to .NET Core and .NET 5 and later versions.
2+
title: Migrate C++/CLI projects to .NET
3+
description: Learn about porting C++/CLI projects to .NET.
44
author: mjrousos
5-
ms.date: 10/27/2023
5+
ms.date: 01/23/2024
66
---
77

8-
# How to port a C++/CLI project to .NET Core or .NET 5+
8+
# How to port a C++/CLI project to .NET
99

10-
Beginning with .NET Core 3.1 and Visual Studio 2019, [C++/CLI projects](/cpp/dotnet/dotnet-programming-with-cpp-cli-visual-cpp) can target .NET Core. This support makes it possible to port Windows desktop applications with C++/CLI interop layers to .NET Core/.NET 5+. This article describes how to port C++/CLI projects from .NET Framework to .NET Core 3.1.
10+
Beginning with Visual Studio 2019, [C++/CLI projects](/cpp/dotnet/dotnet-programming-with-cpp-cli-visual-cpp) can target .NET. This support makes it possible to port Windows desktop applications with C++/CLI interop layers from .NET Framework to .NET. This article describes how to port C++/CLI projects from .NET Framework to .NET.
1111

1212
## C++/CLI .NET Core limitations
1313

14-
There are some important limitations to porting C++/CLI projects to .NET Core compared to other languages:
14+
There are some important limitations with C++/CLI projects and .NET compared to .NET Framework:
1515

16-
- C++/CLI support for .NET Core is Windows only.
17-
- C++/CLI projects can't target .NET Standard, only .NET Core or .NET Framework.
18-
- C++/CLI projects don't support the new SDK-style project file format. Instead, even when targeting .NET Core, C++/CLI projects use the existing *.vcxproj* file format.
19-
- C++/CLI projects can't multitarget multiple .NET platforms. If you need to build a C++/CLI project for both .NET Framework and .NET Core, use separate project files.
20-
- .NET Core doesn't support `-clr:pure` or `-clr:safe` compilation, only the new `-clr:netcore` option (which is equivalent to `-clr` for .NET Framework).
16+
- Compiling a C++/CLI project to an executable isn't supported. You must compile to a DLL.
17+
- C++/CLI support for .NET is Windows only.
18+
- C++/CLI projects can't target .NET Standard.
19+
- C++/CLI projects don't support the newer SDK-style project file format. Instead, C++/CLI projects use the same _.vcxproj_ file format that other Visual Studio C++ projects use.
20+
- C++/CLI projects can't target multiple .NET platforms. If you need to build a C++/CLI project for both .NET and .NET Framework, use separate project files.
21+
- .NET doesn't support `-clr:pure` or `-clr:safe` compilation, only the newer `-clr:netcore` option (which is equivalent to `-clr` for .NET Framework).
2122

2223
## Port a C++/CLI project
2324

24-
To port a C++/CLI project to .NET Core, make the following changes to the *.vcxproj* file. These migration steps differ from the steps needed for other project types because C++/CLI projects don't use SDK-style project files.
25+
To port a C++/CLI project to .NET, make the following changes to the _.vcxproj_ file. These migration steps differ from the steps needed for other project types because C++/CLI projects don't use SDK-style project files.
2526

26-
1. Replace `<CLRSupport>true</CLRSupport>` properties with `<CLRSupport>NetCore</CLRSupport>`. This property is often in configuration-specific property groups, so you might need to replace it in multiple places.
27-
2. Replace `<TargetFrameworkVersion>` properties with `<TargetFramework>netcoreapp3.1</TargetFramework>`. Be sure to change the tag as well as the value.
28-
3. Remove any .NET Framework references to `System`, `System.Data`, `System.Windows.Forms`, and `System.Xml`, like `<Reference Include="System" />`. .NET Core SDK assemblies are automatically referenced when using `<CLRSupport>NetCore</CLRSupport>`.
29-
4. Update API usage in *.cpp* files, as necessary, to remove APIs unavailable to .NET Core. Because C++/CLI projects tend to be fairly thin interop layers, there are often not many changes needed. You can use the [.NET Portability Analyzer](../../standard/analyzers/portability-analyzer.md) to identify unsupported .NET APIs used by C++/CLI binaries just as with purely managed binaries.
27+
01. Replace `<CLRSupport>true</CLRSupport>` properties with `<CLRSupport>NetCore</CLRSupport>`. This property is often in configuration-specific property groups, so you might need to replace it in multiple places.
28+
01. Replace `<TargetFrameworkVersion>` properties with `<TargetFramework>net8.0</TargetFramework>`. Be sure to change the tag and value.
29+
01. Remove any .NET Framework references to `System`, `System.Data`, `System.Windows.Forms`, and `System.Xml`, like `<Reference Include="System" />`. .NET SDK assemblies are automatically referenced when using `<CLRSupport>NetCore</CLRSupport>`.
30+
01. Update API usage in _.cpp_ files, as necessary, to remove APIs unavailable to .NET. Because C++/CLI projects tend to be fairly thin interop layers, there are often not many changes needed. You can use the [.NET Portability Analyzer](../../standard/analyzers/portability-analyzer.md) to identify unsupported .NET APIs used by C++/CLI binaries.
31+
01. If your project was an executable, perform the following steps:
32+
01. Change the project type to a library.
33+
01. Create a new .NET executable project.
34+
01. In the .NET executable project, add reference the C++/CLI .NET library.
3035

3136
### WPF and Windows Forms usage
3237

33-
.NET Core C++/CLI projects can use Windows Forms and WPF APIs. To use these Windows desktop APIs, you need to add explicit framework references to the UI libraries. SDK-style projects that use Windows desktop APIs reference the necessary framework libraries automatically by using the `Microsoft.NET.Sdk.WindowsDesktop` SDK. Because C++/CLI projects don't use the SDK-style project format, they need to add explicit framework references when targeting .NET Core.
38+
.NET C++/CLI projects can use Windows Forms and WPF APIs. To use these Windows desktop APIs, you need to add explicit framework references to the UI libraries. SDK-style projects that use Windows desktop APIs reference the necessary framework libraries automatically by using the `Microsoft.NET.Sdk.WindowsDesktop` SDK. Because C++/CLI projects don't use the SDK-style project format, they need to add explicit framework references when targeting .NET Core.
3439

35-
To use Windows Forms APIs, add this reference to the *.vcxproj* file:
40+
To use Windows Forms APIs, add this reference to the _.vcxproj_ file:
3641

3742
```xml
3843
<!-- Reference all of Windows Forms -->
3944
<FrameworkReference Include="Microsoft.WindowsDesktop.App.WindowsForms" />
4045
```
4146

42-
To use WPF APIs, add this reference to the *.vcxproj* file:
47+
To use WPF APIs, add this reference to the _.vcxproj_ file:
4348

4449
```xml
4550
<!-- Reference all of WPF -->
4651
<FrameworkReference Include="Microsoft.WindowsDesktop.App.WPF" />
4752
```
4853

49-
To use both Windows Forms and WPF APIs, add this reference to the *.vcxproj* file:
54+
To use both Windows Forms and WPF APIs, add this reference to the _.vcxproj_ file:
5055

5156
```xml
5257
<!-- Reference the entirety of the Windows desktop framework:
@@ -58,27 +63,27 @@ Currently, it's not possible to add these references by using Visual Studio's re
5863

5964
## Build without MSBuild
6065

61-
It's also possible to build C++/CLI projects without using MSBuild. Follow these steps to build a C++/CLI project for .NET Core directly with *cl.exe* and *link.exe*:
62-
63-
1. When compiling, pass `-clr:netcore` to *cl.exe*.
64-
2. Reference necessary .NET Core reference assemblies.
65-
3. When linking, provide the .NET Core app host directory as a `LibPath`, so that *ijwhost.lib* can be found.
66-
4. Copy *ijwhost.dll* from the .NET Core app host directory to the project's output directory.
67-
5. Make sure a [runtimeconfig.json](https://github.com/dotnet/sdk/blob/main/documentation/specs/runtime-configuration-file.md) file exists for the first component of the application that will run managed code. For latest versions of Visual Studio, a *runtime.config* file is created and copied automatically.
68-
69-
For older versions of Visual Studio, if the application has a native entry point, you need to manually create the following *runtimeconfig.json* file for the first C++/CLI library to use the .NET Core runtime. If a C++/CLI library is called from a managed entry point, the library doesn't need a *runtimeconfig.json* file, because the entry point assembly has one that's used when starting the runtime.
70-
71-
```json
72-
{
73-
"runtimeOptions": {
74-
"tfm": "netcoreapp3.1",
75-
"framework": {
76-
"name": "Microsoft.NETCore.App",
77-
"version": "3.1.0"
78-
}
79-
}
80-
}
81-
```
66+
It's also possible to build C++/CLI projects without using MSBuild. Follow these steps to build a C++/CLI project for .NET Core directly with _cl.exe_ and _link.exe_:
67+
68+
01. When compiling, pass `-clr:netcore` to _cl.exe_.
69+
01. Reference necessary .NET reference assemblies.
70+
01. When linking, provide the .NET app host directory as a `LibPath`, so that _ijwhost.lib_ can be found.
71+
01. Copy _ijwhost.dll_ from the .NET app host directory to the project's output directory.
72+
01. Make sure a [_runtimeconfig.json_](https://github.com/dotnet/sdk/blob/main/documentation/specs/runtime-configuration-file.md) file exists for the first component of the application that runs managed code. For latest versions of Visual Studio, a _runtime.config_ file is created and copied automatically.
73+
74+
For older versions of Visual Studio, if the application has a native entry point, you need to manually create the following _runtimeconfig.json_ file for the first C++/CLI library to use the .NET runtime. If a C++/CLI library is called from a managed entry point, the library doesn't need a _runtimeconfig.json_ file, because the entry point assembly has one that is used when starting the runtime.
75+
76+
```json
77+
{
78+
"runtimeOptions": {
79+
"tfm": "net8.0",
80+
"framework": {
81+
"name": "Microsoft.NETCore.App",
82+
"version": "8.0.0"
83+
}
84+
}
85+
}
86+
```
8287

8388
> [!NOTE]
8489
> C++/CLI assemblies that target .NET 7 or a later version are always loaded into the default <xref:System.Runtime.Loader.AssemblyLoadContext>. However, in .NET 6 and earlier versions, C++/CLI assemblies might be loaded multiple times, each time into a new `AssemblyLoadContext`. If the first time that managed code in a C++/CLI assembly is executed:

0 commit comments

Comments
 (0)