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

Примечание.

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

Внимание

Эта информация относится к предварительному выпуску продукта, который может быть существенно изменен до его коммерческого выпуска. Майкрософт не предоставляет никаких гарантий, явных или подразумеваемых, относительно приведенных здесь сведений.

В текущем выпуске см . версию .NET 8 этой статьи.

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

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

Средства сборки WebAssembly .NET

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

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

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

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

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

Примечание.

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

Использование машинного кода

Добавьте в приложение Blazor WebAssembly простую функцию в машинном коде C:

  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. В файле проекта приложения добавьте NativeFileReference для Test.c:

    <ItemGroup>
      <NativeFileReference Include="Test.c" />
    </ItemGroup>
    
  5. В компоненте Razor добавьте DllImportAttribute для функции 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 (dotnet.wasm). Когда компиляция приложения завершится, запустите приложение и получите вычисленное значение факториала.

Обратные вызовы управляемого метода C++

Пометьте управляемые методы, которые передаются в C++ с помощью атрибута [UnmanagedCallersOnly].

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

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

Примечание.

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

Зависимости машинного кода в пакете NuGet

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

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

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

Чтобы использовать SkiaSharp в приложении Blazor WebAssembly, сделайте следующее:

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

    dotnet add package –-prerelease SkiaSharp.Views.Blazor
    

    Примечание.

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

  2. Добавьте в приложение компонент 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);
        }
    }
    
  3. Скомпилируйте приложение, что может занять несколько минут. Запустите приложение и перейдите к компоненту NativeDependencyExample по адресу /native-dependency-example.

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

Средства сборки .NET WebAssembly