從 Visual Studio 2019 開始, C++/CLI 專案 可以以 .NET 為目標。 這項支援可讓您將具有 C++/CLI Interop 層的 Windows 傳統型應用程式從 .NET Framework 移植到 .NET。 本文說明如何將C++/CLI 專案從 .NET Framework 移植到 .NET。
C++/CLI .NET Core 限制
與 .NET Framework 相比,C++/CLI 專案和 .NET 有一些重要的限制:
- 不支援將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選項(相當於-clr.NET Framework)。
移植C++/CLI 專案
若要將C++/CLI 專案移植到 .NET,請對 .vcxproj 檔案進行下列變更。 這些移轉步驟與其他項目類型所需的步驟不同,因為C++/CLI 專案不會使用 SDK 樣式的項目檔。
- 將屬性取代
<CLRSupport>true</CLRSupport>為<CLRSupport>NetCore</CLRSupport>。 此屬性通常位於組態特定的屬性群組中,因此您可能需要在多個位置取代它。 - 將屬性取代
<TargetFrameworkVersion>為<TargetFramework>net8.0</TargetFramework>。 請務必變更標籤和值。 - 移除對
System、System.Data、System.Windows.Forms和System.Xml等項目的任何 .NET Framework 參考,像<Reference Include="System" />。 使用<CLRSupport>NetCore</CLRSupport>時,會自動參考 .NET SDK 元件。 - 視需要更新 .cpp 檔案中的 API 使用量,以移除 .NET 無法使用的 API。 因為 C++/CLI 專案往往是相當精簡的互操作層,因此通常不需要太多變更。 您可以使用 .NET 可移植性分析器 來識別C++/CLI 二進位檔所使用的不支援的 .NET API。
- 如果您的專案是可執行檔,請執行下列步驟:
- 將專案類型變更為函式庫。
- 建立新的 .NET 可執行文件專案。
- 在 .NET 可執行文件專案中,新增對 C++/CLI .NET 庫的參考。
WPF 和 Windows Forms 使用方式
.NET C++/CLI 專案可以使用 Windows Forms 和 WPF API。 若要使用這些 Windows 桌面 API,您必須將明確的架構參考新增至 UI 連結庫。 使用 Windows 桌面 API 的 SDK 樣式專案會自動使用 Microsoft.NET.Sdk.WindowsDesktop SDK 參考必要的框架庫。 由於C++/CLI 專案不會使用 SDK 樣式的專案格式,因此它們必須在以 .NET Core 為目標時新增明確的架構參考。
若要使用 Windows Forms API,請將此參考新增至 .vcxproj 檔案:
<!-- Reference all of Windows Forms -->
<FrameworkReference Include="Microsoft.WindowsDesktop.App.WindowsForms" />
若要使用 WPF API,請將此參考新增至 .vcxproj 檔案:
<!-- Reference all of WPF -->
<FrameworkReference Include="Microsoft.WindowsDesktop.App.WPF" />
若要同時使用 Windows Forms 和 WPF API,請將此參考新增至 .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" />
目前無法使用 Visual Studio 的參考管理員來新增這些參考。 反而,請手動編輯項目檔來更新。 在 Visual Studio 中,您必須先卸載專案。 您也可以使用另一個編輯器,例如 Visual Studio Code。
不使用 MSBuild 建置
您也可以不使用 MSBuild 來建置C++/CLI 專案。 請遵循下列步驟,直接使用 cl.exe 和 link.exe 建置 C++/CLI 的 .NET Core 專案:
編譯時,傳遞
-clr:netcore至 cl.exe。參考必要的 .NET 參考元件。
連結時,請提供 .NET 應用程式主機目錄做為
LibPath,以便找到 ijwhost.lib 。將 ijwhost.dll 從 .NET 應用程式主機目錄複製到項目的輸出目錄。
請確定用於執行受控程式碼的應用程式的第一個元件有 runtimeconfig.json 文件。 針對最新版的Visual Studio,會自動建立並複製 runtime.config 檔案。
對於舊版 Visual Studio,如果應用程式有原生進入點,您必須手動建立下列runtimeconfig.json檔案,讓第一個 C++ /CLI 連結庫使用 .NET 運行時間。 如果從受控入口點呼叫C++/CLI 連結庫,則該連結庫不需要 runtimeconfig.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/runtime 問題。