C++/CLI プロジェクトを .NET Core に移植する方法How to port a C++/CLI project to .NET Core

.NET Core 3.1 以降および Visual Studio 2019 バージョン 16.4 以降では、C++/CLI プロジェクト で .NET Core をターゲットにすることができます。Beginning with .NET Core 3.1 and Visual Studio 2019 version 16.4, C++/CLI projects can target .NET Core. このサポートにより、Windows デスクトップ アプリケーションを、C++/CLI 相互運用層を使用して .NET Core に移植できるようになります。This support makes it possible to port Windows desktop applications with C++/CLI interop layers to .NET Core. この記事では、C++/CLI プロジェクトを .NET Framework から .NET Core 3.1 に移植する方法について説明します。This article describes how to port C++/CLI projects from .NET Framework to .NET Core 3.1.

C++/CLI .NET Core の制限事項C++/CLI .NET Core limitations

他の言語と比較して、C++/CLI プロジェクトを .NET Core に移植する場合、いくつかの重要な制限があります。There are some important limitations to porting C++/CLI projects to .NET Core compared to other languages:

  • .NET Core の C++/CLI サポートは Windows のみです。C++/CLI support for .NET Core is Windows only.
  • C++/CLI プロジェクトで .NET Standard をターゲットにすることはできません。できるのは .NET Core (または .NET Framework) だけです。C++/CLI projects can't target .NET Standard, only .NET Core (or .NET Framework).
  • C++/CLI プロジェクトでは、SDK スタイルの新しいプロジェクト ファイル形式はサポートされていません。C++/CLI projects don't support the new SDK-style project file format. 代わりに、C++/CLI プロジェクトでは、.NET Core をターゲットにしている場合でも、既存の vcxproj ファイル形式が使用されます。Instead, even when targeting .NET Core, C++/CLI projects use the existing vcxproj file format.
  • C++/CLI プロジェクトでは、複数の .NET プラットフォームをマルチターゲットに設定することはできません。C++/CLI projects can't multitarget multiple .NET platforms. .NET Framework と .NET Core の両方に対して C++/CLI プロジェクトをビルドする必要がある場合は、個別のプロジェクト ファイルを使用します。If you need to build a C++/CLI project for both .NET Framework and .NET Core, use separate project files.
  • .NET Core では、-clr:pure または -clr:safe のコンパイルはサポートされておらず、新しい -clr:netcore オプション (.NET Framework の -clr に相当) のみがサポートされています。.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).

C++/CLI プロジェクトを移植するPort a C++/CLI project

C++/CLI プロジェクトを .NET Core に移植するには、次のように vcxproj ファイルに変更を加えます。To port a C++/CLI project to .NET Core, make the following changes to the vcxproj file. C++/CLI プロジェクトでは SDK スタイルのプロジェクト ファイルが使用されていないため、これらの移行手順は、他のプロジェクト タイプに必要な手順とは異なります。These migration steps differ from the steps needed for other project types because C++/CLI projects don't use SDK-style project files.

  1. <CLRSupport>true</CLRSupport> プロパティを <CLRSupport>NetCore</CLRSupport> に置き換えます。Replace <CLRSupport>true</CLRSupport> properties with <CLRSupport>NetCore</CLRSupport>. このプロパティは、多くの場合、構成固有のプロパティ グループに含まれているため、場合によっては、複数箇所でこれを置き換える必要があります。This property is often in configuration-specific property groups, so you may need to replace it in multiple places.
  2. <TargetFrameworkVersion> プロパティを <TargetFramework>netcoreapp3.1</TargetFramework> に置き換えます。Replace <TargetFrameworkVersion> properties with <TargetFramework>netcoreapp3.1</TargetFramework>.
  3. .NET Framework の参照 (<Reference Include="System" /> など) をすべて削除します。Remove any .NET Framework references (like <Reference Include="System" />). <CLRSupport>NetCore</CLRSupport> を使用すると、.NET Core SDK アセンブリが自動的に参照されます。.NET Core SDK assemblies are automatically referenced when using <CLRSupport>NetCore</CLRSupport>.
  4. 必要に応じて、cpp ファイルの API 使用状況を更新して、.NET Core で使用できない API を削除します。Update API usage in cpp files, as necessary, to remove APIs unavailable to .NET Core. C++/CLI プロジェクトはかなり薄い相互運用層になる傾向があるため、多くの変更が必要になることはほとんどありません。Because C++/CLI projects tend to be fairly thin interop layers, there are often not many changes needed. .NET Portability Analyzer を使用すると、純粋なマネージド バイナリと同じように、C++/CLI バイナリで使用されるサポートされていない .NET API を識別できます。The .NET Portability Analyzer can be used to identify unsupported .NET APIs used by C++/CLI binaries just as with purely managed binaries. コードの移植性の判断と、.NET Core API で動作するプロジェクトの更新のガイドラインについては、ライブラリの移植に関するガイダンスを参照してください。Guidelines for determining code portability and updating projects to work with .NET Core APIs are available in the library porting guidance.

WPF と Windows フォームの使用方法WPF and Windows Forms usage

.NET Core C++/CLI プロジェクトでは、Windows フォーム API と WPF API を使用できます。.NET Core C++/CLI projects can use Windows Forms and WPF APIs. これらの Windows デスクトップ API を使用するには、明示的なフレームワーク参照を UI ライブラリに追加する必要があります。To use these Windows desktop APIs, you need to add explicit framework references to the UI libraries. Windows デスクトップ API を使用する SDK スタイルのプロジェクトは、Microsoft.NET.Sdk.WindowsDesktop SDK を使用して、必要なフレームワーク ライブラリを自動的に参照します。SDK-style projects that use Windows desktop APIs reference the necessary framework libraries automatically by using the Microsoft.NET.Sdk.WindowsDesktop SDK. C++/CLI プロジェクトでは SDK スタイルのプロジェクト形式を使用していないため、.NET Core をターゲットにするときに、明示的なフレームワーク参照を追加する必要があります。Because C++/CLI projects don't use the SDK-style project format, they need to add explicit framework references when targeting .NET Core.

Windows フォーム API を使用するには、次の参照を vcxproj ファイルに追加します。To use Windows Forms APIs, add this reference to the vcxproj file:

<!-- Reference all of Windows Forms -->
<FrameworkReference Include="Microsoft.WindowsDesktop.App.WindowsForms" />

WPF API を使用するには、次の参照を vcxproj ファイルに追加します。To use WPF APIs, add this reference to the vcxproj file:

<!-- Reference all of WPF -->
<FrameworkReference Include="Microsoft.WindowsDesktop.App.WPF" />

Windows フォーム API と WPF API の両方を使用するには、次の参照を vcxproj ファイルに追加します。To use both Windows Forms and WPF APIs, add this reference to the vcxproj file:

<!-- Reference the entirety of the Windows desktop framework:
     Windows Forms, WPF, and the types that provide integration between them -->
<FrameworkReference Include="Microsoft.WindowsDesktop.App" />

現時点では、Visual Studio の参照マネージャーを使用してこれらの参照を追加することはできません。Currently, it's not possible to add these references using Visual Studio's reference manager. 代わりに、プロジェクト ファイルを手動で更新します。Instead, update the project file manually. この更新は、Visual Studio でプロジェクトをアンロードしてからプロジェクト ファイルを編集することによって行うことができます。This update can be done in Visual Studio by unloading the project and then editing the project file. VS Code などの別のエディターを使用することもできます。You can also use another editor like VS Code.

MSBuild なしでビルドするBuild without MSBuild

MSBuild を使用せずに C++/CLI プロジェクトをビルドすることもできます。It's also possible to build C++/CLI projects without using MSBuild. 次の手順に従って、cl.exelink.exe を使用して、.NET Core 向けの C++/CLI プロジェクトを直接ビルドします。Follow these steps to build a C++/CLI project for .NET Core directly with cl.exe and link.exe:

  1. コンパイル時に、cl.exe-clr:netcore を渡します。When compiling, pass -clr:netcore to cl.exe.
  2. 必要な .NET Core 参照アセンブリを参照します。Reference necessary .NET Core reference assemblies.
  3. リンクするときに、.NET Core アプリのホスト ディレクトリを LibPath として指定します (ijwhost.lib が検出されるようにします)。When linking, provide the .NET Core app host directory as a LibPath (so that ijwhost.lib can be found).
  4. ijwhost.dll を (.NET Core アプリのホスト ディレクトリから) プロジェクトの出力ディレクトリにコピーします。Copy ijwhost.dll (from the .NET Core app host directory) to the project's output directory.
  5. マネージド コードを実行するアプリケーションの最初のコンポーネント用に runtimeconfig. json ファイルが存在することを確認します。Make sure a runtimeconfig.json file exists for the first component of the application that will run managed code. アプリケーションにマネージド エントリ ポイントがある場合は、runtime.config ファイルが自動的に作成されてコピーされます。If the application has a managed entry point, a runtime.config file will be created and copied automatically. ただし、アプリケーションにネイティブ エントリ ポイントがある場合は、NET Core ランタイムを使用するために最初の C++/CLI ライブラリ用に runtimeconfig.json ファイルを作成する必要があります。If the application has a native entry point, though, you need to create a runtimeconfig.json file for the first C++/CLI library to use the .NET Core runtime.

既知の問題Known issues

.NET Core をターゲットとする C++/CLI プロジェクトを使用する場合は、注意すべき既知の問題がいくつかあります。There are a couple known issues to look out for when working with C++/CLI projects targeting .NET Core.

  • .NET Core C++/CLI プロジェクトの WPF フレームワーク参照では、現在、シンボルをインポートできないという無関係な警告がいくつか発生しています。A WPF framework reference in .NET Core C++/CLI projects currently causes some extraneous warnings about being unable to import symbols. これらの警告は無視してかまいません。まもなく修正されるはずです。These warnings can be safely ignored and should be fixed soon.

  • アプリケーションにネイティブ エントリ ポイントがある場合、最初にマネージド コードを実行する C++/CLI ライブラリには runtimeconfig.json ファイルが必要です。If the application has a native entry point, the C++/CLI library that first executes managed code needs a runtimeconfig.json file. この構成ファイルは、.NET Core ランタイムの起動時に使用されます。This config file is used when the .NET Core runtime starts. C++/CLI プロジェクトでは、ビルド時に runtimeconfig.json ファイルが自動的に作成されないため、このファイルを手動で生成する必要があります。C++/CLI projects don't create runtimeconfig.json files automatically at build time yet, so the file must be generated manually. C++/CLI ライブラリがマネージド エントリ ポイントから呼び出された場合、その C++/CLI ライブラリには runtimeconfig.json ファイルは必要ありません (ランタイムの起動時に使用されるものがエントリ ポイント アセンブリに含まれているため)。If a C++/CLI library is called from a managed entry point, then the C++/CLI library doesn't need a runtimeconfig.json file (since the entry point assembly will have one that is used when starting the runtime). 簡単なサンプルの runtimeconfig.json ファイルを次に示します。A simple sample runtimeconfig.json file is shown below. 詳しくは、GitHub で仕様を参照してください。For more information, see the spec on GitHub.

    {
          "runtimeOptions": {
             "tfm": "netcoreapp3.1",
             "framework": {
                "name": "Microsoft.NETCore.App",
                "version": "3.1.0"
             }
          }
    }