共用方式為


ASP.NET Core Blazor WebAssembly 原生相依性

注意

這不是這篇文章的最新版本。 關於目前版本,請參閱 本文的 .NET 10 版本

警告

不再支援此版本的 ASP.NET Core。 如需詳細資訊,請參閱 .NET 和 .NET Core 支持原則。 如需目前的版本,請參閱 本文的 .NET 9 版本。

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) 編譯

藉由在應用程式的專案檔中新增 Blazor WebAssembly 項目,以將原生相依性新增至 NativeFileReference 應用程式。 建置專案時,都會由 .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 屬性的官方檔是針對每個 檔 blazor msbuild 組態選項 (dotnet/docs #27395)進行規劃。

使用機器碼

本節示範如何將簡單的原生 C 函式新增至 Blazor WebAssembly 應用程式。

建立新的 Blazor WebAssembly 專案。

在專案中新增一個包含計算階乘的 C 函式的Test.c檔案。

Test.c

int fact(int n)
{
    if (n == 0) return 1;
    return n * fact(n - 1);
}

在應用程式的項目檔中新增 NativeFileReference MSBuild 項目 Test.c (.csproj):

<ItemGroup>
  <NativeFileReference Include="Test.c" />
</ItemGroup>

在Razor元件中,為產生的[DllImport]庫中的函式新增fact屬性,並從元件中的 .NET 程式代碼呼叫Test方法。

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++的 Managed 方法。 以 屬性標示的方法必須是 static。 若要在 Razor 元件中呼叫執行個體方法,請將執行個體的 GCHandle 傳遞至 C++,然後將其傳回原生。 或者,使用一些其他方法來識別元件的執行個體。

[DllImport] 屬性 標示的方法必須使用 函式指標(C# 9 或更新版本), 而不是回呼自變數的委派類型。

注意

針對 [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。

將封裝參考新增至 SkiaSharp.Views.Blazor 專案中的 Blazor WebAssembly 封裝。 使用 Visual Studio 的流程將套件新增至應用程式(管理 NuGet 套件 並選取 包含發行前版本)或在命令殼層中使用 dotnet add package 選項執行 --prerelease 命令:

dotnet add package –-prerelease SkiaSharp.Views.Blazor

注意

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

使用下列項目,將 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);
    }
}

建置應用程式,此程序可能需要幾分鐘的時間。 執行應用程式,並瀏覽至位於 NativeDependencyExample/native-dependency-example元件。

其他資源