英語で読む

次の方法で共有


C++/CLI プロジェクトを .NET に移植する方法

Visual Studio 2019 以降では、C++/CLI プロジェクトで .NET をターゲットにすることができます。 このサポートにより、C++/CLI 相互運用層を使用して、Windows デスクトップ アプリケーションを .NET Framework から .NET に移植できるようになります。 この記事では、C++/CLI プロジェクトを .NET Framework から .NET に移植する方法について説明します。

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

C++/CLI プロジェクトと .NET には、.NET Framework と比べて、いくつかの重要な制限事項があります。

  • C++/CLI プロジェクトの実行可能ファイルへのコンパイルはサポートされていません。 DLL にコンパイルする必要があります。
  • .NET の C++/CLI サポートは Windows のみです。
  • C++/CLI プロジェクトは、.NET Standard をターゲットにすることはできません。
  • C++/CLI プロジェクトでは、新しい SDK スタイルのプロジェクト ファイル形式はサポートされていません。 代わりに、C++/CLI プロジェクトでは、他の Visual Studio C++ プロジェクトで使用されるのと同じ .vcxproj ファイル形式が使用されます。
  • C++/CLI プロジェクトでは、複数の .NET プラットフォームをマルチターゲットに設定することはできません。 .NET と .NET Framework の両方に対して C++/CLI プロジェクトをビルドする必要がある場合は、個別のプロジェクト ファイルを使用してください。
  • .NET では、-clr:pure または -clr:safe のコンパイルはサポートされておらず、新しい -clr:netcore オプション (.NET Framework の -clr に相当) のみがサポートされています。

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

C++/CLI プロジェクトを .NET に移植するには、次のように .vcxproj ファイルに変更を加えます。 C++/CLI プロジェクトでは SDK スタイルのプロジェクト ファイルが使用されていないため、これらの移行手順は、他のプロジェクト タイプに必要な手順とは異なります。

  1. <CLRSupport>true</CLRSupport> プロパティを <CLRSupport>NetCore</CLRSupport> に置き換えます。 このプロパティは、多くの場合、構成固有のプロパティ グループに含まれているため、場合によっては、複数の場所でこれを置き換える必要があります。
  2. <TargetFrameworkVersion> プロパティを <TargetFramework>net8.0</TargetFramework> に置き換えます。 必ずタグと値を変更してください。
  3. <Reference Include="System" /> など、SystemSystem.DataSystem.Windows.FormsSystem.Xml への .NET Framework 参照をすべて削除します。 <CLRSupport>NetCore</CLRSupport> を使用すると、.NET SDK アセンブリが自動的に参照されます。
  4. 必要に応じて、.cpp ファイルの API 使用状況を更新して、.NET で使用できない API を削除してください。 C++/CLI プロジェクトはかなり薄い相互運用層になる傾向があるため、多くの変更が必要になることはほとんどありません。 .NET Portability Analyzer を使用すると、C++/CLI バイナリで使用されるサポートされていない .NET API を識別できます。
  5. プロジェクトが実行可能ファイルである場合は、次の手順を実行してください。
    1. プロジェクト タイプをライブラリに変更してください。
    2. 新しい .NET 実行可能ファイル プロジェクトを作成してください。
    3. .NET 実行可能ファイル プロジェクトで、C++/CLI .NET ライブラリの参照を追加してください。

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

.NET C++/CLI プロジェクトでは、Windows フォームおよび WPF の API を使用できます。 これらの Windows デスクトップ API を使用するには、明示的なフレームワーク参照を UI ライブラリに追加する必要があります。 Windows デスクトップ API を使用する SDK スタイルのプロジェクトは、Microsoft.NET.Sdk.WindowsDesktop SDK を使用して、必要なフレームワーク ライブラリを自動的に参照します。 C++/CLI プロジェクトでは SDK スタイルのプロジェクト形式を使用していないため、.NET Core をターゲットにするときに、明示的なフレームワーク参照を追加する必要があります。

Windows フォーム API を使用するには、次の参照を .vcxproj ファイルに追加します。

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

WPF API を使用するには、次の参照を .vcxproj ファイルに追加します。

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

Windows フォーム API と WPF API の両方を使用するには、次の参照を .vcxproj ファイルに追加します。

XML
<!-- 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 の参照マネージャーを使用してこれらの参照を追加することはできません。 代わりに、プロジェクト ファイルを手動で編集して更新します。 Visual Studio で、まずプロジェクトをアンロードする必要があります。 Visual Studio Code などの別のエディターを使用することもできます。

MSBuild なしでビルドする

MSBuild を使用せずに C++/CLI プロジェクトをビルドすることもできます。 次の手順に従って、cl.exelink.exe を使用して、.NET Core 向けの C++/CLI プロジェクトを直接ビルドします。

  1. コンパイル時に、cl.exe-clr:netcore を渡します。

  2. 必要な .NET 参照アセンブリを参照してください。

  3. リンクするときに、.NET アプリのホスト ディレクトリを LibPath として指定して、ijwhost.lib が検出されるようにしてください。

  4. ijwhost.dll を .NET アプリのホスト ディレクトリからプロジェクトの出力ディレクトリにコピーしてください。

  5. マネージド コードを実行するアプリケーションの最初のコンポーネント用に runtimeconfig. json ファイルが存在することを確認してください。 最新バージョンの Visual Studio では、runtime.config ファイルが自動的に作成され、コピーされます。

    以前のバージョンの Visual Studio の場合、アプリケーションにネイティブ エントリ ポイントがあるときは、.NET ランタイムを使用する最初の C++/CLI ライブラリに対して、次の runtimeconfig.json ファイルを手動で作成する必要があります。 C++/CLI ライブラリがマネージド エントリ ポイントから呼び出された場合、エントリ ポイント アセンブリにはランタイムの起動時に使用される runtimeconfig.json ファイルがあるため、ライブラリには必要ありません。

    JSON
    {
       "runtimeOptions": {
          "tfm": "net8.0",
          "framework": {
          "name": "Microsoft.NETCore.App",
          "version": "8.0.0"
          }
       }
    }
    

注意

.NET 7 以降のバージョンをターゲットとする C++/CLI アセンブリは、常に既定の AssemblyLoadContext に読み込まれます。 ただし、.NET 6 以前のバージョンでは、C++/CLI アセンブリが複数回読み込まれる可能性があり、そのたびに新しい AssemblyLoadContext に読み込まれます。 C++/CLI アセンブリのマネージド コードが最初にどこから実行されるかによって、読み込み先が異なります。

  • 実行元がネイティブの呼び出し元の場合、アセンブリは別個の AssemblyLoadContext に読み込まれます。
  • 実行元がマネージド呼び出し元の場合、アセンブリは呼び出し元と同じ AssemblyLoadContext (通常は既定) に読み込まれます。

C++/CLI アセンブリが常に既定の AssemblyLoadContext に読み込まれるようにするには、エントリ ポイント アセンブリから C++/CLI アセンブリを呼び出す "初期化" スタイルの呼び出しを追加できます。 詳細については、こちらの dotnet、ランタイムに関する問題を参照してください。