Partilhar via


ASP.NET Core Blazor WebAssembly dependências nativas

Observação

Esta não é a versão mais recente deste artigo. Para a versão atual, consulte a versão .NET 10 deste artigo.

Advertência

Esta versão do ASP.NET Core não é mais suportada. Para obter mais informações, consulte a Política de suporte do .NET e .NET Core. Para a versão atual, consulte a versão .NET 10 deste artigo.

Blazor WebAssembly aplicativos podem usar dependências nativas criadas para serem executadas no WebAssembly. Você pode vincular estaticamente dependências nativas ao tempo de execução do .NET WebAssembly usando as ferramentas de compilação .NET WebAssembly, as mesmas ferramentas usadas para compilação antecipada (AOT) um aplicativo Blazor para WebAssembly e para revincular o tempo de execução para remover recursos não utilizados.

Este artigo aplica-se apenas a Blazor WebAssembly.

Ferramentas de compilação do .NET WebAssembly

As ferramentas de compilação do .NET WebAssembly são baseadas no Emscripten, uma cadeia de ferramentas de compilador para a plataforma Web. Para obter mais informações sobre as ferramentas de compilação, incluindo a instalação, consulte ASP.NET Core Blazor WebAssembly build tools and ahead-of-time (AOT) compilation.

Adicione dependências nativas a um aplicativo Blazor WebAssembly adicionando itens de NativeFileReference no arquivo de projeto do aplicativo. Quando o projeto é criado, cada NativeFileReference é passado para o Emscripten pelas ferramentas de compilação do .NET WebAssembly, para que os dados sejam compilados e ligados ao tempo de execução. Em seguida, p/invoke no código nativo do código .NET da aplicação.

Geralmente, qualquer código nativo portátil pode ser usado como uma dependência nativa com Blazor WebAssembly. Você pode adicionar dependências nativas ao código C/C++ ou código compilado anteriormente usando Emscripten:

  • Arquivos de objeto (.o)
  • Ficheiros de arquivo (.a)
  • Código Bitcode (.bc)
  • Módulos WebAssembly autónomos (.wasm)

As dependências pré-compiladas normalmente devem ser compiladas usando a mesma versão do Emscripten utilizada para compilar o ambiente de execução do .NET WebAssembly.

Observação

Para propriedades e destinos Mono/WebAssembly MSBuild, consulte WasmApp.targets (repositório GitHubdotnet/runtime). A documentação oficial para propriedades comuns do MSBuild é planejada de acordo com Document blazor msbuild configuration options (dotnet/docs #27395).

Usar código nativo

Esta seção demonstra como adicionar uma função C nativa simples a um Blazor WebAssembly aplicativo.

Crie um novo projeto Blazor WebAssembly.

Adicione um Test.c arquivo ao projeto com uma função C para calcular fatoriais.

Test.c:

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

Adicione um NativeFileReference item do MSBuild para Test.c no arquivo de projeto do aplicativo (.csproj):

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

Em um Razor componente, adicione um [DllImport] atributo para a fact função na Test biblioteca gerada e chame o fact método no código .NET do 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 você cria o aplicativo com as ferramentas de compilação do .NET WebAssembly instaladas, o código C nativo é compilado e vinculado ao tempo de execução do .NET WebAssembly (dotnet.wasm). Depois que o aplicativo for criado, execute o aplicativo para ver o valor fatorial renderizado.

Retornos de chamada do método gerenciado C++

Rotule métodos gerenciados que são passados para C++ com o [UnmanagedCallersOnly] atributo. O método marcado com o atributo deve ser static. Para chamar um método de instância em um componente Razor, passe um GCHandle da instância para C++ e depois devolva-o para o código nativo. Como alternativa, use algum outro método para identificar a instância do componente.

O método marcado com o atributo [DllImport] deve usar um ponteiro de função (C# 9 ou posterior) em vez de um tipo delegado para o argumento de retorno de chamada.

Observação

Para tipos de ponteiro de função C# em métodos [DllImport], use IntPtr na assinatura do método no lado gerenciado em vez de delegate *unmanaged<int, void>. Para obter mais informações, consulte Retorno de chamada [WASM] do código nativo para o .NET: Não há suporte para a análise de tipos de ponteiro de função em assinaturas (dotnet/runtime #56145).

Empacotar dependências nativas em um pacote NuGet

Os pacotes NuGet podem conter dependências nativas para uso no WebAssembly. Essas bibliotecas e suas funcionalidades nativas ficam disponíveis para qualquer aplicativo Blazor WebAssembly. Os arquivos para as dependências nativas devem ser criados para WebAssembly e empacotados na pasta específica da arquitetura browser-wasm. As dependências específicas do WebAssembly não são referenciadas automaticamente e devem ser referenciadas manualmente como NativeFileReferences. Os autores do pacote podem optar por adicionar as referências nativas incluindo um arquivo de .props no pacote com as referências.

Uso da biblioteca de exemplo SkiaSharp

SkiaSharp é uma biblioteca de gráficos 2D multiplataforma para .NET baseada na biblioteca de gráficos nativos Skia com suporte para Blazor WebAssembly.

A seção demonstra como implementar o SkiaSharp em um Blazor WebAssembly aplicativo.

Adicione uma referência de pacote ao pacote SkiaSharp.Views.Blazor em um projeto Blazor WebAssembly. Use o processo do Visual Studio para adicionar pacotes a uma aplicação (Gerir pacotes NuGet com Incluir pré-lançamento selecionado) ou execute o comando dotnet add package num shell de comando com a opção --prerelease.

dotnet add package –-prerelease SkiaSharp.Views.Blazor

Observação

Para obter orientação sobre como adicionar pacotes a aplicativos .NET, consulte os artigos em Instalar e gerenciar pacotes em Fluxo de trabalho de consumo de pacotes (documentação do NuGet). Confirme as versões corretas do pacote em NuGet.org.

Adicione um componente SKCanvasView ao aplicativo com o seguinte:

  • SkiaSharp e SkiaSharp.Views.Blazor namespaces.
  • Lógica para desenhar na vista de tela do componente 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);
    }
}

Crie o aplicativo, o que pode levar vários minutos. Execute o aplicativo e navegue até o componente NativeDependencyExample em /native-dependency-example.

Recursos adicionais