ASP.NET Core Blazor WebAssembly собственные зависимости

Примечание.

Это не последняя версия этой статьи. Текущий выпуск можно найти в версии этой статьи о .NET 10.

Предупреждение

Эта версия ASP.NET Core больше не поддерживается. Для получения дополнительной информации см. Политику поддержки .NET и .NET Core. Текущий выпуск можно найти в версии этой статьи о .NET 10.

Приложения Blazor WebAssembly могут использовать зависимости в машинном коде, созданные для выполнения в WebAssembly. Вы можете статически связать собственные зависимости с рантаймом .NET WebAssembly с помощью средств сборки .NET WebAssembly, те же самые средства, используемые для компиляции приложения заранее (AOT) в WebAssembly и для пересборки рантайма с целью удаления неиспользуемых функций.

Эта статья относится только к Blazor WebAssembly.

инструменты сборки .NET WebAssembly

Средства сборки .NET WebAssembly основаны на Emscripten, цепочке инструментов компилятора для веб-платформы. Дополнительные сведения о средствах сборки, включая установку, см. в разделе Средства сборки ASP.NET Core и предварительная (AOT) компиляция.

Добавьте зависимости в машинном коде в приложение Blazor WebAssembly путем добавления элементов NativeFileReference в файл проекта приложения. При построении проекта каждый NativeFileReference передается в Emscripten посредством средств сборки .NET WebAssembly, чтобы их скомпилировать и связать со средой выполнения. Затем p/invoke в нативный код из среды .NET кода приложения.

Как правило, в качестве нативной зависимости для Blazor WebAssembly можно использовать любой переносимый нативный код. Вы можете добавить встроенные зависимости в код C/C++ или в код, уже скомпилированный с помощью Emscripten.

  • Файлы объектов (.o)
  • Архивные файлы (.a)
  • Bitcode (.bc)
  • Автономные модули WebAssembly (.wasm)

Предварительно созданные зависимости обычно необходимо создавать с помощью той же версии Emscripten, используемой для сборки среды выполнения .NET WebAssembly.

Примечание.

Сведения о свойствах и целевых объектах Mono/WebAssembly MSBuild см. в WasmApp.targets (репозиторий dotnet/runtime GitHub). Планируется разработка официальной документации по общим свойствам MSBuild в рамках задачи Документировать параметры конфигурации blazor для msbuild (dotnet/docs #27395).

Нативный код

В этом разделе показано, как добавить простую собственную функцию C в Blazor WebAssembly приложение.

Создайте новый проект Blazor WebAssembly .

Добавьте в проект файл с функцией на 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 в созданной библиотеке Test и вызовите метод fact из кода .NET компонента.

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++

Обозначьте управляемые методы, передаваемые в C++, с помощью атрибута [UnmanagedCallersOnly]. Метод, помеченный атрибутом, должен быть static. Чтобы вызвать метод экземпляра в компоненте Razor, передайте GCHandle для экземпляра в C++, а затем передайте его обратно в нативный код. Кроме того, можно использовать другой метод для обнаружения экземпляра компонента.

Метод, помеченный атрибутом,[DllImport] должен использовать указатель функции (C# 9 или более поздней версии), а не тип делегата для аргумента обратного вызова.

Примечание.

Для типов указателей функций C# в методах [DllImport] используйте IntPtr в сигнатуре метода на управляемой стороне вместо delegate *unmanaged<int, void>. Дополнительные сведения см. в разделе [WASM] обратный вызов из нативного кода в .NET: разбор типов указателей функции в сигнатурах не поддерживается (dotnet/runtime #56145).

Упаковка родных зависимостей в пакет NuGet

Пакеты NuGet могут содержать зависимости в машинном коде для использования в WebAssembly. Эти библиотеки и их родные функции доступны для любого приложения Blazor WebAssembly. Файлы для нативных зависимостей нужно скомпилировать для WebAssembly и упаковать в browser-wasmпапку для конкретной архитектуры. Зависимости, специфичные для WebAssembly, не получают ссылок автоматически и должны быть указаны вручную в формате NativeFileReferences. Авторы пакетов могут выбирать добавление нативных ссылок, включая файл .props в пакет вместе с этими ссылками.

Пример использования библиотеки SkiaSharp

SkiaSharp — кроссплатформенная библиотека графики для .NET на основе собственной библиотеки графики Skia с поддержкой Blazor WebAssembly.

В этом разделе показано, как реализовать SkiaSharp в Blazor WebAssembly приложении.

Добавьте ссылку на SkiaSharp.Views.Blazor пакет в Blazor WebAssembly проекте. Используйте процесс Visual Studio для добавления пакетов в приложение (Управление пакетами NuGet с Включить предварительные версии выбрано) или выполните команду dotnet add package в командной оболочке с параметром --prerelease:

dotnet add package –-prerelease SkiaSharp.Views.Blazor

Примечание.

Рекомендации по добавлению пакетов в приложения .NET можно найти в статьях раздела Установка и управление пакетами на странице Потребление пакетов (документация NuGet). Проверьте правильность версий пакета на сайте NuGet.org.

Добавьте в приложение компонент SKCanvasView следующим образом:

  • Пространства имен SkiaSharp и SkiaSharp.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.

Дополнительные ресурсы