for the `fact` function in the generated `Test` library and call the `fact` method from .NET code in the component.
`Pages/NativeCTest.razor`:
```razor
@page "/native-c-test"
@using System.Runtime.InteropServices
Native C
Native C Test
@@fact(3) result: @fact(3)
@code {
[DllImport("Test")]
static extern int fact(int n);
}
```
When you build the app with the **.NET WebAssembly build tools** installed, the native C code is compiled and linked into the .NET WebAssembly runtime (`dotnet.wasm`). After the app is built, run the app to see the rendered factorial value.
## C++ managed method callbacks
Label managed methods that are passed to C++ with the `[UnmanagedCallersOnly]` attribute.
The method marked with the `[UnmanagedCallersOnly]` attribute must be `static`. To call an instance method in a Razor component, pass a `GCHandle` for the instance to C++ and then pass it back to native. Alternatively, use some other method to identify the instance of the component.
The method marked with `[DllImport]` must use a C# 9.0 function pointer rather than a delegate type for the callback argument.
> [!NOTE]
> For C# function pointer types in `[DllImport]` methods, use `IntPtr` in the method signature on the managed side instead of `delegate *unmanaged`. For more information, see [[WASM] callback from native code to .NET: Parsing function pointer types in signatures is not supported (dotnet/runtime #56145)](https://github.com/dotnet/runtime/issues/56145).
## Package native dependencies in a NuGet package
NuGet packages can contain native dependencies for use on WebAssembly. These libraries and their native functionality are then available to any Blazor WebAssembly app. The files for the native dependencies should be built for WebAssembly and packaged in the `browser-wasm` [architecture-specific folder](/nuget/create-packages/supporting-multiple-target-frameworks#architecture-specific-folders). WebAssembly-specific dependencies aren't referenced automatically and must be referenced manually as `NativeFileReference`s. Package authors can choose to add the native references by including a `.props` file in the package with the references.
## SkiaSharp example library use
[SkiaSharp](https://github.com/mono/SkiaSharp) is a cross-platform 2D graphics library for .NET based on the native [Skia graphics library](https://skia.org/), and it now has preview support for Blazor WebAssembly.
> [!WARNING]
> Experimental and preview features are provided for the purpose of collecting feedback and aren't supported for production use.
To use SkiaSharp in a Blazor WebAssembly app:
1. Add a package reference to the [`SkiaSharp.Views.Blazor`](https://www.nuget.org/packages/SkiaSharp.Views.Blazor) package in a Blazor WebAssembly project. Use Visual Studio's process for adding packages to an app (**Manage NuGet Packages**) or execute the [`dotnet add package`](/dotnet/core/tools/dotnet-add-package) command in a command shell:
```dotnetcli
dotnet add package –-prerelease SkiaSharp.Views.Blazor
```
> [!WARNING]
> The [`SkiaSharp.Views.Blazor`](https://www.nuget.org/packages/SkiaSharp.Views.Blazor) package is a prerelease NuGet package not supported for production use.
1. Add a `SKCanvasView` component to the app with the following:
* `SkiaSharp` and `SkiaSharp.Views.Blazor` namespaces.
* Logic to draw in the SkiaSharp Canvas View component (`SKCanvasView`).
`Pages/NativeDependencyExample.razor`:
```razor
@page "/native-dependency-example"
@using SkiaSharp
@using SkiaSharp.Views.Blazor
Native dependency
Native dependency example with SkiaSharp
@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);
}
}
```
1. Build the app, which might take several minutes. Run the app and navigate to the `NativeDependencyExample` component at `/native-dependency-example`.