ASP.NET Core Blazor WebAssembly: native Abhängigkeiten

Hinweis

Dies ist nicht die neueste Version dieses Artikels. Informationen zum aktuellen Release finden Sie in der .NET 8-Version dieses Artikels.

Wichtig

Diese Informationen beziehen sich auf ein Vorabversionsprodukt, das vor der kommerziellen Freigabe möglicherweise noch wesentlichen Änderungen unterliegt. Microsoft gibt keine Garantie, weder ausdrücklich noch impliziert, hinsichtlich der hier bereitgestellten Informationen.

Informationen zum aktuellen Release finden Sie in der .NET 8-Version dieses Artikels.

Blazor WebAssembly-Apps können native Abhängigkeiten verwenden, die für die Ausführung in WebAssembly erstellt wurden. Sie können native Abhängigkeiten mithilfe der .NET-WebAssembly-Buildtools statisch mit der .NET-WebAssembly-Runtime verknüpfen. Dabei handelt es sich um dieselben Tools, die auch für die Ahead-of-Time-Kompilierung (AOT) einer Blazor-App für WebAssembly oder für die erneute Verknüpfung der Runtime zum Entfernen ungenutzter Features verwendet werden.

Dieser Artikel gilt nur für Blazor WebAssembly.

.NET WebAssembly-Buildtools

Die .NET-WebAssembly-Buildtools basieren auf Emscripten, einer Compilertoolkette für die Webplattform. Weitere Informationen zu den Buildtools, u. a. zu ihrer Installation, finden Sie unter ASP.NET Core Blazor WebAssembly-Buildtools und Ahead-of-Time-Kompilierung (AOT).

Fügen Sie einer Blazor WebAssembly-App native Abhängigkeiten hinzu, indem Sie NativeFileReference-Elemente in die Projektdatei der App einfügen. Bei der Erstellung des Projekts werden alle NativeFileReference-Elemente von den .NET WebAssembly-Build-Tools an Emscripten übergeben, damit sie kompiliert und in die Laufzeitumgebung eingebunden werden. Als Nächstes rufen Sie über p/invoke den nativen Code aus dem .NET-Code der App auf.

Im Allgemeinen kann jeder portierbare native Code als native Abhängigkeit mit Blazor WebAssembly verwendet werden. Sie können C/C++-Code oder Code, der zuvor mit Emscripten kompiliert wurde, native Abhängigkeiten hinzufügen:

  • Objektdateien (.o)
  • Archivdateien (.a)
  • Bitcode (.bc)
  • Eigenständige WebAssembly-Module (.wasm)

Vordefinierte Abhängigkeiten müssen in der Regel mit derselben Version von Emscripten erstellt werden, die zum Erstellen der .NET-WebAssembly-Runtime verwendet wird.

Hinweis

Informationen zu Mono/WebAssembly-MSBuild-Eigenschaften und -Zielen finden Sie unter WasmApp.targets (im GitHub-Repository „dotnet/runtime“). Die offizielle Dokumentation zu MSBuild-Eigenschaften ist für das Dokument zu Blazor-MSBuild-Konfigurationsoptionen (dotnet/docs #27395) geplant.

Verwenden von nativem Code

Fügen Sie einer Blazor WebAssembly-App eine einfache native C-Funktion hinzu:

  1. Erstellen Sie ein neues Blazor WebAssembly -Projekt.

  2. Fügen Sie dem Projekt eine Datei Test.c hinzu.

  3. Fügen Sie eine C-Funktion zum Berechnen von Fakultäten hinzu.

    Test.c:

    int fact(int n)
    {
        if (n == 0) return 1;
        return n * fact(n - 1);
    }
    
  4. Fügen Sie in der App-Projektdatei ein NativeFileReference-Element für Test.c hinzu:

    <ItemGroup>
      <NativeFileReference Include="Test.c" />
    </ItemGroup>
    
  5. Fügen Sie in einer Razor-Komponente ein DllImportAttribute für die fact-Funktion in der generierten Test-Bibliothek hinzu, und rufen Sie die fact-Methode über den .NET-Code in der Komponente auf.

    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);
    }
    

Wenn Sie die App mit den installierten .NET-WebAssembly-Buildtools erstellen, wird der native C-Code kompiliert und mit der .NET WebAssembly-Runtime (dotnet.wasm) verknüpft. Nachdem die App erstellt wurde, führen Sie sie aus, um den gerenderten Fakultätswert anzuzeigen.

Rückrufe verwalteter C++-Methoden

Beschriften Sie verwaltete Methoden, die an C++ übergeben werden, mit dem [UnmanagedCallersOnly]-Attribut.

Die mit dem [UnmanagedCallersOnly]-Attribut markierte Methode muss static sein. Übergeben Sie zum Aufrufen einer Instanzmethode in einer Razor-Komponente ein GCHandle für die Instanz an C++, und übergeben Sie sie dann wieder an den nativen Code. Verwenden Sie alternativ eine andere Methode, um die Instanz der Komponente zu identifizieren.

Die mit [DllImport] markierte Methode muss einen C# 9.0-Funktionszeiger anstelle eines Delegattyps für das Rückrufargument verwenden.

Hinweis

Verwenden Sie für C#-Funktionszeigertypen in [DllImport]-Methoden IntPtr in der Methodensignatur auf der verwalteten Seite anstelle von delegate *unmanaged<int, void>. Weitere Informationen finden Sie auf GitHub im Artikel zu Rückrufen aus nativem Code zu .NET: Analysieren von Funktionszeigertypen in Signaturen wird nicht unterstützt [WASM] (dotnet/runtime #56145).

Packen nativer Abhängigkeiten in ein NuGet-Paket

NuGet-Pakete können native Abhängigkeiten für die Verwendung in WebAssembly enthalten. Diese Bibliotheken und ihre native Funktionalität stehen dann für jede Blazor WebAssembly-App zur Verfügung. Die Dateien für die nativen Abhängigkeiten sollten für WebAssembly erstellt und im architekturspezifischen Ordnerbrowser-wasm gepackt werden. Auf WebAssembly-spezifische Abhängigkeiten wird nicht automatisch verwiesen, sie müssen manuell als NativeFileReference referenziert werden. Paketautoren können die nativen Verweise hinzufügen, indem sie eine .props-Datei mit den Verweisen in das Paket einschließen.

Verwendung der SkiaSharp-Beispielbibliothek

SkiaSharp ist eine plattformübergreifende 2D-Grafikbibliothek für .NET, die auf der nativen Skia-Grafikbibliothek basiert und Blazor WebAssembly unterstützt.

So verwenden Sie SkiaSharp in einer Blazor WebAssembly-App:

  1. Fügen Sie einen Paketverweis auf das SkiaSharp.Views.Blazor-Paket in ein Blazor WebAssembly-Projekt ein. Verwenden Sie das Verfahren von Visual Studio zum Hinzufügen von Paketen zu einer App (NuGet-Pakete verwalten mit ausgewählter Option Vorabversion einbeziehen), oder führen Sie den Befehl dotnet add package in einer Befehlsshell aus:

    dotnet add package –-prerelease SkiaSharp.Views.Blazor
    

    Hinweis

    Einen Leitfaden zum Hinzufügen von Paketen zu .NET-Apps finden Sie in Installieren und Verwalten von Paketen unter Workflow der Nutzung von Paketen (NuGet-Dokumentation). Überprüfen Sie unter NuGet.org, ob die richtige Paketversion verwendet wird.

  2. Fügen Sie der App eine SKCanvasView-Komponente mit folgenden Merkmalen hinzu:

    • Namespaces SkiaSharp und SkiaSharp.Views.Blazor
    • Logik zum Zeichnen in der SkiaSharp-CanvasView-Komponente (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. Erstellen Sie die App, was einige Minuten dauern kann. Führen Sie die App aus, und navigieren Sie zur NativeDependencyExample-Komponente unter /native-dependency-example.

Zusätzliche Ressourcen

.NET WebAssembly-Buildtools