ASP.NET Core Blazor WebAssembly のネイティブの依存関係

注意

これは、この記事の最新バージョンではありません。 現在のリリースについては、この記事の .NET 8 バージョンを参照してください。

重要

この情報はリリース前の製品に関する事項であり、正式版がリリースされるまでに大幅に変更される可能性があります。 Microsoft はここに示されている情報について、明示か黙示かを問わず、一切保証しません。

現在のリリースについては、この記事の .NET 8 バージョンを参照してください。

Blazor WebAssembly アプリは、WebAssembly での実行用にビルドされた、ネイティブの依存関係を使用できます。 .NET WebAssembly ビルド ツールを使用すれば、ネイティブの依存関係を .NET WebAssembly ランタイムに静的にリンクできます。このビルド ツールは、Blazor アプリを WebAssembly に Ahead-Of-Time (AOT) コンパイルしたり、ランタイムを再リンクして未使用の機能を削除したりするために使用するツールと同じです。

この記事は Blazor WebAssembly にのみ該当します。

.NET WebAssembly ビルド ツール

.NET WebAssembly ビルド ツールは、Web プラットフォーム用のコンパイラ ツールチェーンである Emscripten をベースにしています。 インストールを含むビルド ツールの詳細については、「ASP.NET Core Blazor WebAssembly ビルド ツールと Ahead-Of-Time (AOT) コンパイル」を参照してください。

アプリのプロジェクト ファイルに NativeFileReference 項目を追加することで、ネイティブの依存関係を Blazor WebAssembly アプリに追加します。 プロジェクトをビルドすると、.NET WebAssembly ビルド ツールによって各 NativeFileReference が Emscripten に渡されて、コンパイルされ、ランタイムにリンクされます。 次に、アプリの .NET コードからネイティブ コードへの p/invoke を実行します。

一般に、Blazor WebAssembly と共に任意の移植可能なネイティブ コードをネイティブの依存関係として使用できます。 ネイティブの依存関係は、C/C++ コードにも、Emscripten を使用して以前にコンパイルしたコードにも追加できます。

  • オブジェクト ファイル (.o)
  • アーカイブ ファイル (.a)
  • Bitcode (.bc)
  • スタンドアロンの WebAssembly モジュール (.wasm)

ビルド済みの依存関係については通常、.NET WebAssembly ランタイムのビルドに使用するのと同じバージョンの Emscripten を使用してビルドする必要があります。

Note

Mono/WebAssembly MSBuild のプロパティとターゲットについては、WasmApp.targets (dotnet/runtime GitHub リポジトリ) を参照してください。 一般的な MSBuild プロパティに関する公式ドキュメントは、ドキュメント Blazor MSBuild 構成オプション (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.c のための NativeFileReference を追加します。

    <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 の関数ポインターを使用する必要があります。

Note

[DllImport] メソッドでの C# 関数ポインター型の場合は、delegate *unmanaged<int, void> ではなく、マネージ側のメソッド シグネチャで IntPtr を使用します。 詳細については、「[WASM] ネイティブ コードから .NET へのコールバック: シグネチャでの関数ポインター型の解析はサポートされていません (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
    

    Note

    .NET アプリへのパッケージの追加に関するガイダンスについては、「パッケージ利用のワークフロー」 (NuGet ドキュメント) の "パッケージのインストールと管理" に関する記事を参照してください。 NuGet.org で正しいパッケージ バージョンを確認します。

  2. 以下を使用して SKCanvasView コンポーネントをアプリに追加します。

    • SkiaSharp および SkiaSharp.Views.Blazor 名前空間。
    • SkiaSharp Canvas View コンポーネント (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-example にある NativeDependencyExample コンポーネントに移動します。

その他の資料

.NET WebAssembly ビルド ツール