Przeczytaj w języku angielskim

Udostępnij za pośrednictwem


Jak przeportować projekt C++/CLI na platformę .NET

Począwszy od programu Visual Studio 2019, projekty C++/CLI mogą być przeznaczone dla platformy .NET. Ta obsługa umożliwia przenoszenie aplikacji klasycznych systemu Windows z warstwami międzyoperacyjnymi języka C++/interfejsu wiersza polecenia z programu .NET Framework do platformy .NET. W tym artykule opisano sposób przenoszenia projektów C++/CLI z programu .NET Framework do platformy .NET.

Ograniczenia języka C++/CLI platformy .NET Core

Istnieją pewne ważne ograniczenia dotyczące projektów języka C++/interfejsu wiersza polecenia i platformy .NET w porównaniu z programem .NET Framework:

  • Kompilowanie projektu C++/CLI do pliku wykonywalnego nie jest obsługiwane. Należy skompilować do biblioteki DLL.
  • Obsługa języka C++/CLI dla platformy .NET jest tylko systemem Windows.
  • Projekty C++/CLI nie mogą być przeznaczone dla platformy .NET Standard.
  • Projekty C++/CLI nie obsługują nowszego formatu pliku projektu w stylu zestawu SDK. Zamiast tego projekty C++/CLI używają tego samego formatu pliku .vcxproj , którego używają inne projekty visual Studio C++.
  • Projekty C++/CLI nie mogą być przeznaczone dla wielu platform .NET. Jeśli musisz utworzyć projekt C++/CLI dla platformy .NET i .NET Framework, użyj oddzielnych plików projektu.
  • Platforma .NET nie obsługuje -clr:pure ani -clr:safe kompilacji— tylko nowsza -clr:netcore opcja (która jest równoważna programowi -clr .NET Framework).

Przenoszenie projektu C++/CLI

Aby przeportować projekt C++/CLI na platformę .NET, wprowadź następujące zmiany w pliku .vcxproj . Te kroki migracji różnią się od kroków wymaganych dla innych typów projektów, ponieważ projekty C++/CLI nie używają plików projektów w stylu zestawu SDK.

  1. Zastąp <CLRSupport>true</CLRSupport> właściwości ciągiem <CLRSupport>NetCore</CLRSupport>. Ta właściwość jest często w grupach właściwości specyficznych dla konfiguracji, więc może być konieczne zastąpienie jej w wielu miejscach.
  2. Zastąp <TargetFrameworkVersion> właściwości ciągiem <TargetFramework>net8.0</TargetFramework>. Pamiętaj, aby zmienić tag i wartość.
  3. Usuń wszystkie odwołania programu .NET Framework do System, System.Data, System.Windows.Formsi System.Xml, na przykład <Reference Include="System" />. Zestawy zestawu SDK platformy .NET są automatycznie przywołyne podczas korzystania z programu <CLRSupport>NetCore</CLRSupport>.
  4. Zaktualizuj użycie interfejsu API w plikach .cpp w razie potrzeby, aby usunąć interfejsy API niedostępne dla platformy .NET. Ponieważ projekty C++/CLI zwykle są dość cienkimi warstwami międzyoperacyjnymi, często nie trzeba wiele zmian. Analizator przenośności platformy .NET służy do identyfikowania nieobsługiwanych interfejsów API platformy .NET używanych przez pliki binarne języka C++/CLI.
  5. Jeśli projekt był plikiem wykonywalnym, wykonaj następujące kroki:
    1. Zmień typ projektu na bibliotekę.
    2. Utwórz nowy projekt wykonywalny platformy .NET.
    3. W projekcie wykonywalnego platformy .NET dodaj odwołanie do biblioteki .NET języka C++/CLI.

Użycie WPF i Windows Forms

Projekty języka .NET C++/CLI mogą używać interfejsów API windows Forms i WPF. Aby korzystać z tych interfejsów API pulpitu systemu Windows, należy dodać jawne odwołania do platformy do bibliotek interfejsu użytkownika. Projekty w stylu zestawu SDK korzystające z interfejsów API klasycznych systemu Windows odwołują się do niezbędnych bibliotek platformy automatycznie przy użyciu zestawu Microsoft.NET.Sdk.WindowsDesktop SDK. Ponieważ projekty języka C++/CLI nie używają formatu projektu w stylu zestawu SDK, muszą dodawać jawne odwołania do platformy podczas określania wartości docelowej dla platformy .NET Core.

Aby użyć interfejsów API formularzy systemu Windows, dodaj to odwołanie do pliku .vcxproj :

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

Aby użyć interfejsów API WPF, dodaj to odwołanie do pliku .vcxproj :

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

Aby użyć interfejsów API windows Forms i WPF, dodaj to odwołanie do pliku .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" />

Obecnie nie można dodać tych odwołań przy użyciu menedżera odwołań programu Visual Studio. Zamiast tego zaktualizuj plik projektu, edytując go ręcznie. W programie Visual Studio należy najpierw zwolnić projekt. Możesz również użyć innego edytora, takiego jak Visual Studio Code.

Kompilowanie bez programu MSBuild

Istnieje również możliwość kompilowania projektów C++/CLI bez korzystania z programu MSBuild. Wykonaj następujące kroki, aby utworzyć projekt C++/CLI dla platformy .NET Core bezpośrednio przy użyciu cl.exe i link.exe:

  1. Podczas kompilowania przekaż -clr:netcore do cl.exe.

  2. Odwołaj się do niezbędnych zestawów odwołań platformy .NET.

  3. Podczas łączenia podaj katalog hosta aplikacji platformy .NET jako LibPath, aby można było znaleźć plik ijwhost.lib .

  4. Skopiuj ijwhost.dll z katalogu hosta aplikacji platformy .NET do katalogu wyjściowego projektu.

  5. Upewnij się, że istnieje plik runtimeconfig.json dla pierwszego składnika aplikacji, który uruchamia kod zarządzany. W przypadku najnowszych wersji programu Visual Studio plik runtime.config jest tworzony i kopiowany automatycznie.

    W przypadku starszych wersji programu Visual Studio, jeśli aplikacja ma natywny punkt wejścia, należy ręcznie utworzyć następujący plik runtimeconfig.json dla pierwszej biblioteki języka C++/interfejsu wiersza polecenia, aby używać środowiska uruchomieniowego platformy .NET. Jeśli biblioteka C++/CLI jest wywoływana z zarządzanego punktu wejścia, biblioteka nie potrzebuje pliku runtimeconfig.json , ponieważ zestaw punktu wejścia ma taki, który jest używany podczas uruchamiania środowiska uruchomieniowego.

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

Uwaga

Zestawy C++/CLI przeznaczone dla platformy .NET 7 lub nowszej są zawsze ładowane do domyślnej wersji AssemblyLoadContext. Jednak w przypadku platformy .NET 6 i starszych wersji zestawy języka C++/CLI mogą być ładowane wiele razy, za każdym razem do nowego AssemblyLoadContextelementu . Jeśli po raz pierwszy kod zarządzany w zestawie C++/CLI jest wykonywany:

  • Jest elementem wywołującym natywnym, zestaw jest ładowany do oddzielnego AssemblyLoadContextobiektu .
  • Jest z zarządzanego obiektu wywołującego, zestaw jest ładowany do tego samego AssemblyLoadContext , co obiekt wywołujący, zwykle domyślny.

Aby zawsze załadować zestaw C++/CLI do domyślnego AssemblyLoadContextelementu , możesz dodać wywołanie stylu "inicjowanie" z zestawu punktu wejścia do zestawu C++/CLI. Aby uzyskać więcej informacji, zobacz ten problem z dotnet/runtime.