ASP.NET Core Blazor WebAssembly 本机依赖项

注意

此版本不是本文的最新版本。 有关当前版本,请参阅本文.NET 9 版本。

警告

此版本的 ASP.NET Core 不再受支持。 有关详细信息,请参阅 .NET 和 .NET Core 支持策略。 有关当前版本,请参阅本文.NET 9 版本。

重要

此信息与预发布产品相关,相应产品在商业发布之前可能会进行重大修改。 Microsoft 对此处提供的信息不提供任何明示或暗示的保证。

有关当前版本,请参阅本文.NET 9 版本。

Blazor WebAssembly 应用可以使用生成的本机依赖项在 WebAssembly 上运行。 可以使用 .NET WebAssembly 生成工具将本机依赖项静态链接到 .NET WebAssembly 运行时,这些工具还可用于将 应用提前 (AOT) 编译到 WebAssembly,并Blazor。

本文仅适用于 Blazor WebAssembly。

.NET WebAssembly 生成工具

.NET WebAssembly 生成工具基于 Emscripten,这是一个用于 Web 平台的编译器工具链。 有关生成工具(包括安装)的详细信息,请参阅 ASP.NET CoreBlazor WebAssembly 生成工具和预先 (AOT) 编译

通过在应用程序的项目文件中添加 Blazor WebAssembly 项,将本机依赖项添加到 NativeFileReference 应用。 生成项目时,每个 NativeFileReference 都由 .NET WebAssembly 生成工具传递给 Emscripten,以便对其进行编译并链接到运行时。 接下来,从应用程序的 .NET 代码使用 p/invoke 进入本机代码。

通常,任何可移植的本机代码都可以用作带有 Blazor WebAssembly 的本机依赖项。 可以将本机依赖项添加到 C/C++ 代码或以前使用 Emscripten 编译的代码:

  • 对象文件 (.o)
  • 存档文件 (.a)
  • Bitcode (.bc
  • 独立 WebAssembly 模块 (.wasm)

通常必须使用用于生成 .NET WebAssembly 运行时的同一版本的 Emscripten 生成预生成依赖项。

注意

若要了解 Mono/WebAssembly MSBuild 属性和目标,请参阅 WasmApp.targetsdotnet/runtime GitHub 存储库)。 根据文档 Blazor MSBuild 配置选项 (dotnet/docs #27395) 计划常见 MSBuild 属性的官方文档。

使用本机代码

本部分演示如何向应用添加简单的本机 C 函数 Blazor WebAssembly 。

创建一个新的 Blazor WebAssembly 项目。

将包含计算阶乘的 C 函数的文件添加到项目中。

Test.c:

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

NativeFileReference 应用的项目文件 (Test.c) 中添加一个 MS Build 项目元素 .csproj:

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

在Razor组件中,为库[DllImport]中生成的函数添加Test,并调用组件中的 .NET 代码中的fact方法。

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++ 托管方法回叫

使用[UnmanagedCallersOnly]属性标记托管方法,并将其传递给C++。 用特性标记的方法必须是 static。 若要在 Razor 组件中调用实例方法,请向 C++ 传递实例的 GCHandle,然后将它传递回本机。 或者,使用一些其他方法来标识组件的实例。

[DllImport] 特性 标记的方法必须使用 函数指针(C# 9 或更高版本), 而不是回调参数的委托类型。

注意

对于 [DllImport] 方法中的 C# 函数指针类型,在托管端的方法签名中使用 IntPtr 而不是 delegate *unmanaged<int, void>。 有关详细信息,请参阅从本机代码到 .NET 的 [WASM] 回调:不支持在签名中分析函数指针类型(dotnet/runtime#56145)。

在 NuGet 包中打包本机依赖项

NuGet 包可以包含在 WebAssembly 使用的本机依赖项。 这些库及其本机功能随后可供任何 Blazor WebAssembly 应用使用。 本机依赖项的文件应为 WebAssembly 生成,并打包到特定于 browser-wasm体系结构的文件夹中。 不自动引用特定于 WebAssembly 的依赖项,必须作为 NativeFileReference 手动引用。 包作者可以通过在带有引用的包中包含 .props 文件来选择添加本机引用。

SkiaSharp 示例库使用

SkiaSharp 是基于本机 Skia 图形库的适用于 .NET 的跨平台 2D 图形库,并且支持 Blazor WebAssembly。

本部分演示如何在 Blazor WebAssembly 应用中实现 SkiaSharp。

SkiaSharp.Views.Blazor 项目中添加对 Blazor WebAssembly 包的包引用。 使用 Visual Studio 的过程将包添加到应用(在管理 NuGet 包时选择包含预发行版)或在命令行界面中使用dotnet add package选项执行--prerelease命令:

dotnet add package –-prerelease SkiaSharp.Views.Blazor

注意

有关将包添加到 .NET 应用的指南,请参阅包使用工作流(NuGet 文档)中“安装和管理包”下的文章。 在 NuGet.org 中确认正确的包版本。

使用以下内容将 SKCanvasView 组件添加到应用:

  • SkiaSharpSkiaSharp.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 组件。

其他资源