ASP.NET Core Blazor WebAssembly 原生相依性

注意

這不是這篇文章的最新版本。 如需目前版本,請參閱本文的 .NET 8 版本

重要

這些發行前產品的相關資訊在產品正式發行前可能會有大幅修改。 Microsoft 對此處提供的資訊,不做任何明確或隱含的瑕疵擔保。

如需目前版本,請參閱本文的 .NET 8 版本

Blazor WebAssembly 應用程式可以使用為在 WebAssembly 上執行而建置的原生相依性。 您可以使用 .NET WebAssembly 組建工具,以靜態方式將原生相依性連結至 .NET WebAssembly 執行階段,.NET WebAssembly 組建工具是用來預先 (AOT) 編譯Blazor 應用程式,以及重新連結執行階段以移除未使用功能的相同工具。

本文僅適用於 Blazor WebAssembly。

.NET WebAssembly 組建工具

.NET WebAssembly 組建工具是以 Web 平台的編譯器工具鏈 Emscripten 為基礎。 如需建置工具及安裝的詳細資訊,請參閱 ASP.NET Core Blazor WebAssembly 建置工具和預先 (AOT) 編譯

藉由在應用程式的專案檔中新增 NativeFileReference 項目,以將原生相依性新增至 Blazor WebAssembly 應用程式。 建置專案時,都會由 .NET WebAssembly 組建工具將每個 NativeFileReference 傳遞至 Emscripten,以便進行編譯並將其連結至執行階段。 接下來,p/invoke 從應用程式的 .NET 程式碼進入機器碼。

一般而言,任何可攜原生程式碼都可以作為 Blazor WebAssembly 的原生相依性。 您可以將原生相依性新增至 C/C++ 程式碼,或先前使用 Emscripten 編譯的程式碼:

  • 目的檔 (.o)
  • 封存檔 (.a)
  • Bitcode (.bc)
  • 獨立 WebAssembly 模組 (.wasm)

建置預先建置的相依性時,通常必須使用與建置 .NET WebAssembly 執行階段所用的相同 Emscripten 版本。

注意

關於 Mono/WebAssembly MSBuild 屬性和目標,請參閱 WasmApp.targets (dotnet/runtime GitHub 存放庫)。 常見 MSBuild 屬性的官方文件是按照 Document blazor msbuild configuration options (dotnet/docs #27395) 進行規劃的。

使用機器碼

將簡單的原生 C 函式新增至 Blazor WebAssembly 應用程式:

  1. 建立新的 Blazor WebAssembly 專案。

  2. Test.c 檔案新增至專案。

  3. 新增用於計算階乘的 C 函式。

    Test.c

    int fact(int n)
    {
        if (n == 0) return 1;
        return n * fact(n - 1);
    }
    
  4. 在應用程式的專案檔中新增 Test.cNativeFileReference

    <ItemGroup>
      <NativeFileReference Include="Test.c" />
    </ItemGroup>
    
  5. 在 Razor 元件中,在產生的 Test 程式庫中新增 fact 函式的 DllImportAttribute,並透過此元件中的 .NET 程式碼呼叫 fact 方法。

    Pages/NativeCTest.razor

    @page "/native-c-test"
    @using System.Runtime.InteropServices
    
    <PageTitle>Native C</PageTitle>
    
    <h1>Native C Test</h1>
    
    <p>
        @@fact(3) result: @fact(3)
    </p>
    
    @code {
        [DllImport("Test")]
        static extern int fact(int n);
    }
    

當您使用所安裝的 .NET WebAssembly 組建工具建置應用程式時,會編譯原生 C 程式碼,並將其連結至 .NET WebAssembly 執行階段 (dotnet.wasm)。 建置應用程式之後,執行應用程式以查看轉譯的階乘值。

C++ 受控方法回呼

使用 [UnmanagedCallersOnly] 屬性傳遞至 C++ 的標籤受控方法。

[UnmanagedCallersOnly] 屬性標示的方法必須是 static。 若要在 Razor 元件中呼叫執行個體方法,請將執行個體的 GCHandle 傳遞至 C++,然後將其傳回原生。 或者,使用一些其他方法來識別元件的執行個體。

使用 [DllImport] 標記的方法必須使用 C# 9.0 函式指標,而不是回呼引數的委派類型。

注意

針對 [DllImport] 方法中的 C# 函式指標類型,請在受控端的方法簽章中使用 IntPtr,而不是 delegate *unmanaged<int, void>。 如需詳細資訊,請參閱從機器碼到 .NET 的 [WASM] 回呼:不支援在簽章中剖析函式指標類型 (dotnet/runtime #56145)

在 NuGet 封裝中封裝原生相依性

NuGet 封裝可以包含原生相依性,以用於 WebAssembly。 這些程式庫及其原生功能接著便可供任何 Blazor WebAssembly 應用程式使用。 應針對 WebAssembly 建置原生相依性的檔案,並將其封裝在 browser-wasm架構特定資料夾中。 不會自動參考 WebAssembly 特定相依性,而且必須作為 NativeFileReference 以手動方式參考。 封裝作者可以選擇新增原生參考,方法是在包含參考的封裝中加入 .props 檔案。

SkiaSharp 範例程式庫用法

SkiaSharp 是以原生 Skia 圖形庫為基礎的 .NET 跨平台 2D 圖形庫,支援 Blazor WebAssembly。

若要在 Blazor WebAssembly 應用程式中使用 SkiaSharp:

  1. 將封裝參考新增至 Blazor WebAssembly 專案中的 SkiaSharp.Views.Blazor 封裝。 使用 Visual Studio 程序,將封裝新增至應用程式 (管理已選取 [包含發行前版本] 的 NuGet 封裝),或在命令殼層中執行 dotnet add package 命令:

    dotnet add package –-prerelease SkiaSharp.Views.Blazor
    

    注意

    如需將套件新增至 .NET 應用程式的指引,請參閱在套件取用工作流程 (NuGet 文件)安裝及管理套件底下的文章。 在 NuGet.org 確認正確的套件版本。

  2. 使用下列項目,將 SKCanvasView 元件新增至應用程式:

    • SkiaSharpSkiaSharp.Views.Blazor 命名空間。
    • 在 SkiaSharp 畫布檢視元件 (SKCanvasView) 中繪製的邏輯。

    Pages/NativeDependencyExample.razor

    @page "/native-dependency-example"
    @using SkiaSharp
    @using SkiaSharp.Views.Blazor
    
    <PageTitle>Native dependency</PageTitle>
    
    <h1>Native dependency example with SkiaSharp</h1>
    
    <SKCanvasView OnPaintSurface="OnPaintSurface" />
    
    @code {
        private void OnPaintSurface(SKPaintSurfaceEventArgs e)
        {
            var canvas = e.Surface.Canvas;
    
            canvas.Clear(SKColors.White);
    
            using var paint = new SKPaint
            {
                Color = SKColors.Black,
                IsAntialias = true,
                TextSize = 24
            };
    
            canvas.DrawText("SkiaSharp", 0, 24, paint);
        }
    }
    
  3. 建置應用程式,此程序可能需要幾分鐘的時間。 執行應用程式,並瀏覽至位於 /native-dependency-exampleNativeDependencyExample元件。

其他資源

.NET WebAssembly 組建工具