ASP.NET Core Blazor WebAssembly 本机依赖项

注意

此版本不是本文的最新版本。 对于当前版本,请参阅此文的 .NET 8 版本

重要

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

对于当前版本,请参阅此文的 .NET 8 版本

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

本文仅适用于 Blazor WebAssembly。

.NET WebAssembly 生成工具

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

通过在应用程序的项目文件中添加 NativeFileReference 项,将本机依赖项添加到 Blazor WebAssembly 应用。 生成项目时,每个 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 应用:

  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. 在应用程序的项目文件中为 Test.c 添加 NativeFileReference

    <ItemGroup>
      <NativeFileReference Include="Test.c" />
    </ItemGroup>
    
  5. 在 Razor 组件中,为生成的 Test 库中的 fact 函数添加 DllImportAttribute,并从组件中的 .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++ 的托管方法。

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

标记为 [DllImport] 的方法必须使用 C# 9.0 函数指针,而不是回叫参数的委托类型。

注意

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

在 NuGet 包中打包本机依赖项

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

SkiaSharp 示例库使用

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

若要在 Blazor WebAssembly 应用中使用 SkiaSharp,请执行以下操作:

  1. 在 Blazor WebAssembly 项目中添加对 SkiaSharp.Views.Blazor 包的包引用。 使用 Visual Studio 的进程将包添加到应用(“管理 NuGet 包”,并选中“包括预发行版”)或在命令行界面中执行 dotnet add package 命令:

    dotnet add package –-prerelease SkiaSharp.Views.Blazor
    

    注意

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

  2. 使用以下内容将 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);
        }
    }
    
  3. 生成应用,这可能需要几分钟时间。 运行应用并导航到 /native-dependency-example 处的 NativeDependencyExample 组件。

其他资源

.NET WebAssembly 生成工具