Jak přenést projekt C++/CLI do .NET

Počínaje sadou Visual Studio 2019 můžou projekty C++/CLI cílit na .NET. Tato podpora umožňuje portovat desktopové aplikace windows s vrstvami spolupráce C++/CLI z rozhraní .NET Framework do .NET. Tento článek popisuje, jak portovat projekty C++/CLI z rozhraní .NET Framework do .NET.

Omezení C++/CLI .NET Core

U projektů C++/CLI a .NET v porovnání s rozhraním .NET Framework platí některá důležitá omezení:

  • Kompilace projektu C++/CLI do spustitelného souboru není podporovaná. Musíte kompilovat do DLL.
  • Podpora C++/CLI pro .NET je pouze Windows.
  • Projekty C++/CLI nemůžou cílit na .NET Standard.
  • Projekty C++/CLI nepodporují novější formát souboru projektu ve stylu sady SDK. Místo toho projekty C++/CLI používají stejný formát souboru .vcxproj , který používají jiné projekty Visual Studio C++.
  • Projekty C++/CLI nemůžou cílit na více platforem .NET. Pokud potřebujete vytvořit projekt C++/CLI pro .NET i .NET Framework, použijte samostatné soubory projektu.
  • .NET nepodporuje kompilaci -clr:pure ani -clr:safe, pouze novější možnost -clr:netcore (která je ekvivalentní -clr pro .NET Framework).

Přenést projekt C++/CLI

Pokud chcete přenést projekt C++/CLI do .NET, proveďte v souboru .vcxproj následující změny. Tyto kroky migrace se liší od kroků potřebných pro jiné typy projektů, protože projekty C++/CLI nepoužívají soubory projektů ve stylu sady SDK.

  1. Nahraďte <CLRSupport>true</CLRSupport> vlastnosti <CLRSupport>NetCore</CLRSupport>. Tato vlastnost je často ve skupinách vlastností specifických pro konfiguraci, takže ji možná budete muset nahradit na více místech.
  2. Nahraďte <TargetFrameworkVersion> vlastnosti <TargetFramework>net8.0</TargetFramework>. Nezapomeňte změnit značku a hodnotu.
  3. Odeberte všechny odkazy rozhraní .NET Framework na System, System.Data, System.Windows.Forms, a System.Xml, jako <Reference Include="System" />. Sestavení sady .NET SDK jsou při použití <CLRSupport>NetCore</CLRSupport> automaticky přidávána jako reference.
  4. Podle potřeby aktualizujte využití rozhraní API ve .cpp souborech, abyste odstranili rozhraní API, která nejsou dostupná pro .NET. Vzhledem k tomu, že projekty C++/CLI mají tendenci být poměrně tenké vrstvy vzájemné spolupráce, často není potřeba mnoho změn. Analyzátor přenositelnosti .NET můžete použít k identifikaci nepodporovaných rozhraní .NET API používaných binárními soubory C++/CLI.
  5. Pokud byl váš projekt spustitelný, proveďte následující kroky:
    1. Změňte typ projektu na knihovnu.
    2. Vytvořte nový spustitelný projekt .NET.
    3. V projektu spustitelného souboru .NET přidejte odkaz na knihovnu C++/CLI .NET.

Použití WPF a Windows Forms

Projekty .NET C++/CLI můžou používat rozhraní API windows Forms a WPF. Pokud chcete tato desktopová rozhraní API systému Windows používat, musíte do knihoven uživatelského rozhraní přidat explicitní odkazy na architekturu. Projekty ve stylu sady SDK, které používají desktopová rozhraní API systému Windows, automaticky odkazují na potřebné knihovny architektury pomocí Microsoft.NET.Sdk.WindowsDesktop sady SDK. Vzhledem k tomu, že projekty C++/CLI nepoužívají formát projektu ve stylu sady SDK, musí při cílení na .NET Core přidat explicitní odkazy na architekturu.

Pokud chcete použít rozhraní API modelu Windows Forms, přidejte tento odkaz na soubor .vcxproj :

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

Pokud chcete použít rozhraní API WPF, přidejte tento odkaz do souboru .vcxproj :

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

Chcete-li použít rozhraní API modelu Windows Forms i WPF, přidejte tento odkaz na soubor .vcxproj :

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

V současné době není možné tyto odkazy přidat pomocí správce odkazů sady Visual Studio. Místo toho soubor projektu aktualizujte tak, že ho upravíte ručně. Ve Visual Studio je potřeba nejprve odpojit projekt. Můžete také použít jiný editor, jako je Visual Studio Code.

Sestavení bez nástroje MSBuild

Je také možné vytvářet projekty C++/CLI bez použití nástroje MSBuild. Pomocí následujícího postupu sestavte projekt C++/CLI pro .NET Core přímo s cl.exe a link.exe:

  1. Při kompilaci předejte -clr:netcore argumentu cl.exe.

  2. Odkazy na potřebná referenční sestavení .NET

  3. Při propojování zadejte hostitelský adresář aplikace .NET jako LibPathadresář , aby bylo možné najít ijwhost.lib .

  4. Zkopírujte ijwhost.dll z hostitelského adresáře aplikace .NET do výstupního adresáře projektu.

  5. Ujistěte se , že pro první komponentu aplikace, která spouští spravovaný kód, existuje souborruntimeconfig.json. V případě nejnovějších verzí sady Visual Studio se vytvoří soubor runtime.config a zkopíruje se automaticky.

    Pokud má aplikace nativní vstupní bod pro starší verze sady Visual Studio, musíte pro první knihovnu C++/CLI pro použití modulu runtime .NET ručně vytvořit následující soubor runtimeconfig.json . Pokud je knihovna C++/CLI volána z řízeného vstupního bodu, knihovna nepotřebuje runtimeconfig.json soubor, protože sestavení pro vstupní bod ho obsahuje a používá se při spuštění modulu runtime.

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

Poznámka:

Sestavení C++/CLI, která cílí na .NET 7 nebo novější verzi, se vždy načtou do výchozího AssemblyLoadContext. V .NET 6 a starších verzích se však sestavení C++/CLI můžou načíst vícekrát, pokaždé do nového AssemblyLoadContext. Pokud se spustí první spravovaný kód v sestavení C++/CLI:

  • Pochází od nativního volajícího, sestavení je načteno do samostatného AssemblyLoadContext.
  • Pokud pochází ze spravovaného volajícího, načte se sestavení do stejného AssemblyLoadContext jako volající, což je obvykle výchozí možností.

Pokud chcete vždy načíst sestavení C++/CLI do výchozího AssemblyLoadContextnastavení, můžete do sestavení C++/CLI přidat volání stylu inicializace z sestavení vstupního bodu. Další informace najdete v tomto problému s dotnet/runtime.