Condividi tramite


ASP.NET Core Blazor WebAssembly dipendenze native

Nota

Questa non è la versione più recente di questo articolo. Per la versione corrente, vedere la versione .NET 10 di questo articolo.

Avviso

Questa versione di ASP.NET Core non è più supportata. Per altre informazioni, vedere .NET e .NET Core Support Policy. Per la versione corrente, vedere la versione .NET 10 di questo articolo.

Blazor WebAssembly le app possono usare le dipendenze native create per l'esecuzione in WebAssembly. È possibile collegare in modo statico le dipendenze native al runtime .NET WebAssembly usando gli strumenti di compilazione .NET WebAssembly, gli stessi strumenti usati per la compilazione ahead-of-time (AOT) di un'app Blazor in WebAssembly e per ricollegare il runtime per rimuovere le funzionalità inutilizzate.

Questo articolo si applica solo a Blazor WebAssembly.

Strumenti di compilazione .NET WebAssembly

Gli strumenti di compilazione .NET WebAssembly sono basati su Emscripten, una toolchain del compilatore per la piattaforma Web. Per altre informazioni sugli strumenti di compilazione, inclusa l'installazione, vedere ASP.NET Core Blazor WebAssembly build tools and ahead-of-time (AOT) compilation.

Aggiungere dipendenze native a un'app Blazor WebAssembly aggiungendo NativeFileReference elementi nel file di progetto dell'app. Quando il progetto viene compilato, ogni NativeFileReference viene passato a Emscripten dagli strumenti di compilazione .NET WebAssembly in modo che vengano compilati e collegati al runtime. Successivamente, p/invoke nel codice nativo partendo dal codice .NET dell'app.

In genere, qualsiasi codice nativo portabile può essere usato come dipendenza nativa con Blazor WebAssembly. È possibile aggiungere dipendenze native al codice C/C++ o al codice compilato in precedenza usando Emscripten:

  • File oggetto (.o)
  • File di archiviazione (.a)
  • Bitcode (.bc)
  • Moduli WebAssembly autonomi (.wasm)

Le dipendenze predefinite devono in genere essere compilate usando la stessa versione di Emscripten usata per compilare il runtime .NET WebAssembly.

Nota

Per le proprietà e le destinazioni Mono/WebAssembly MSBuild, vedere WasmApp.targets (repository dotnet/runtime GitHub). La documentazione ufficiale per le proprietà comuni di MSBuild è prevista per Document Blazor opzioni di configurazione di MSBuild (dotnet/docs #27395).

Usare il codice nativo

Questa sezione illustra come aggiungere una semplice funzione C nativa a un'app Blazor WebAssembly .

Creare un nuovo progetto Blazor WebAssembly .

Aggiungere un Test.c file al progetto con una funzione C per i fattoriali di calcolo.

Test.c:

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

Aggiungere un NativeFileReference elemento MSBuild per Test.c nel file di progetto dell'app (.csproj):

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

In un componente Razor aggiungere un attributo [DllImport] per la funzione fact nella libreria Test generata e chiamare il metodo fact dal codice .NET nel componente.

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

Quando si compila l'app con gli strumenti di compilazione .NET WebAssembly installati, il codice C nativo viene compilato e collegato al runtime .NET WebAssembly (dotnet.wasm). Dopo aver sviluppato l'app, eseguire l'app per vedere il valore fattoriale renderizzato.

Callback di metodo gestito in C++

Etichettare i metodi gestiti che vengono passati a C++ con l'attributo [UnmanagedCallersOnly]. Il metodo contrassegnato con l'attributo deve essere static. Per chiamare un metodo di istanza nel componente Razor, passare un'istanza GCHandle a C++ e quindi passarla di nuovo al codice nativo. In alternativa, usare un altro metodo per identificare l'istanza del componente.

Il metodo contrassegnato con l'attributo [DllImport] deve usare un puntatore a funzione (C# 9 o versione successiva) anziché un tipo delegato per l'argomento di callback.

Nota

Nei metodi [DllImport], per i tipi di puntatore a funzione C#, usare IntPtr nella firma del metodo sul lato gestito anziché delegate *unmanaged<int, void>. Per ulteriori informazioni, vedere [WASM]: callback dal codice nativo a .NET: l'analisi dei tipi di puntatori di funzione nelle firme non è supportata (dotnet/runtime #56145).

Creare un pacchetto di dipendenze native in un pacchetto NuGet

I pacchetti NuGet possono contenere dipendenze native da usare in WebAssembly. Queste librerie e le relative funzionalità native sono quindi disponibili per qualsiasi Blazor WebAssembly app. I file per le dipendenze native devono essere compilati per WebAssembly e inseriti in un pacchetto nella cartella specifica dell'architettura browser-wasm. Le dipendenze specifiche di WebAssembly non vengono menzionate automaticamente e devono essere aggiunte manualmente come NativeFileReferences. Gli autori di pacchetti possono scegliere di aggiungere i riferimenti nativi includendo un .props file nel pacchetto con i riferimenti.

Uso della libreria di esempio SkiaSharp

SkiaSharp è una libreria grafica 2D multipiattaforma per .NET basata sulla libreria grafica nativa Skia con supporto per Blazor WebAssembly.

La sezione illustra come implementare SkiaSharp in un'app Blazor WebAssembly .

Aggiungere un riferimento al pacchetto SkiaSharp.Views.Blazor in progetto Blazor WebAssembly. Usare il processo di Visual Studio per aggiungere pacchetti a un'app (Gestisci pacchetti NuGet con Includi versioni preliminari selezionato) oppure eseguire il comando dotnet add package in una shell dei comandi con l'opzione --prerelease:

dotnet add package –-prerelease SkiaSharp.Views.Blazor

Nota

Per indicazioni sull'aggiunta di pacchetti alle app .NET, vedere gli articoli in Installare e gestire pacchetti all'indirizzo Package consumption workflow (documentazione nuGet). Confermare le versioni corrette del pacchetto all'indirizzo NuGet.org.

Aggiungere il componente SKCanvasView all'interno dell'app con quanto segue:

  • SkiaSharp spazi dei nomi e SkiaSharp.Views.Blazor .
  • Logica per disegnare nel componente 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);
    }
}

Compilare l'app, che potrebbe richiedere alcuni minuti. Eseguire l'app e passare al componente NativeDependencyExample a /native-dependency-example.

Risorse aggiuntive