Skip to content

Commit 7837139

Browse files
authored
WASM Native Dependencies article UE pass (#34553)
1 parent 2bb3ccb commit 7837139

File tree

1 file changed

+71
-72
lines changed

1 file changed

+71
-72
lines changed

aspnetcore/blazor/webassembly-native-dependencies.md

Lines changed: 71 additions & 72 deletions
Original file line numberDiff line numberDiff line change
@@ -36,64 +36,62 @@ Prebuilt dependencies typically must be built using the same version of Emscript
3636
3737
## Use native code
3838

39-
Add a simple native C function to a Blazor WebAssembly app:
39+
This section demonstrates how to add a simple native C function to a Blazor WebAssembly app.
4040

41-
1. Create a new Blazor WebAssembly project.
42-
1. Add a `Test.c` file to the project.
43-
1. Add a C function for computing factorials.
41+
Create a new Blazor WebAssembly project.
4442

45-
`Test.c`:
43+
Add a `Test.c` file to the project with a C function for computing factorials.
4644

47-
```c
48-
int fact(int n)
49-
{
50-
if (n == 0) return 1;
51-
return n * fact(n - 1);
52-
}
53-
```
45+
`Test.c`:
5446

55-
1. Add a `NativeFileReference` for `Test.c` in the app's project file:
47+
```c
48+
int fact(int n)
49+
{
50+
if (n == 0) return 1;
51+
return n * fact(n - 1);
52+
}
53+
```
5654
57-
```xml
58-
<ItemGroup>
59-
<NativeFileReference Include="Test.c" />
60-
</ItemGroup>
61-
```
55+
Add a `NativeFileReference` MS Build item for `Test.c` in the app's project file (`.csproj`):
6256
63-
1. In a Razor component, add a <xref:System.Runtime.InteropServices.DllImportAttribute> for the `fact` function in the generated `Test` library and call the `fact` method from .NET code in the component.
57+
```xml
58+
<ItemGroup>
59+
<NativeFileReference Include="Test.c" />
60+
</ItemGroup>
61+
```
6462

65-
`Pages/NativeCTest.razor`:
63+
In a Razor component, add a [`[DllImport]` attribute](xref:System.Runtime.InteropServices.DllImportAttribute) for the `fact` function in the generated `Test` library and call the `fact` method from .NET code in the component.
6664

67-
```razor
68-
@page "/native-c-test"
69-
@using System.Runtime.InteropServices
65+
`Pages/NativeCTest.razor`:
7066

71-
<PageTitle>Native C</PageTitle>
67+
```razor
68+
@page "/native-c-test"
69+
@using System.Runtime.InteropServices
7270
73-
<h1>Native C Test</h1>
71+
<PageTitle>Native C</PageTitle>
7472
75-
<p>
76-
@@fact(3) result: @fact(3)
77-
</p>
73+
<h1>Native C Test</h1>
7874
79-
@code {
80-
[DllImport("Test")]
81-
static extern int fact(int n);
82-
}
83-
```
75+
<p>
76+
@@fact(3) result: @fact(3)
77+
</p>
78+
79+
@code {
80+
[DllImport("Test")]
81+
static extern int fact(int n);
82+
}
83+
```
8484

8585
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.
8686

8787
## C++ managed method callbacks
8888

89-
Label managed methods that are passed to C++ with the `[UnmanagedCallersOnly]` attribute.
90-
91-
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.
89+
Label managed methods that are passed to C++ with the [`[UnmanagedCallersOnly]` attribute](xref:System.Runtime.InteropServices.UnmanagedCallersOnlyAttribute). The method marked with the attribute must be `static`. To call an instance method in a Razor component, pass a <xref:System.Runtime.InteropServices.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.
9290

93-
The method marked with `[DllImport]` must use a C# 9.0 function pointer rather than a delegate type for the callback argument.
91+
The method marked with the [`[DllImport]` attribute](xref:System.Runtime.InteropServices.DllImportAttribute) must use a [function pointer (C# 9.0 or later)](/dotnet/csharp/language-reference/proposals/csharp-9.0/function-pointers) rather than a delegate type for the callback argument.
9492

9593
> [!NOTE]
96-
> For C# function pointer types in `[DllImport]` methods, use `IntPtr` in the method signature on the managed side instead of `delegate *unmanaged<int, void>`. 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).
94+
> For C# function pointer types in [`[DllImport]`](xref:System.Runtime.InteropServices.DllImportAttribute) methods, use <xref:System.IntPtr> in the method signature on the managed side instead of `delegate *unmanaged<int, void>`. 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).
9795
9896
## Package native dependencies in a NuGet package
9997

@@ -103,55 +101,56 @@ NuGet packages can contain native dependencies for use on WebAssembly. These lib
103101

104102
[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/) with support for Blazor WebAssembly.
105103

106-
To use SkiaSharp in a Blazor WebAssembly app:
104+
The section demonstrates how to implement SkiaSharp in a Blazor WebAssembly app.
107105

108-
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** with **Include prerelease** selected) or execute the [`dotnet add package`](/dotnet/core/tools/dotnet-add-package) command in a command shell:
106+
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** with **Include prerelease** selected) or execute the [`dotnet add package`](/dotnet/core/tools/dotnet-add-package) command in a command shell with the `--prerelease` option:
109107

110-
```dotnetcli
111-
dotnet add package –-prerelease SkiaSharp.Views.Blazor
112-
```
108+
```dotnetcli
109+
dotnet add package –-prerelease SkiaSharp.Views.Blazor
110+
```
113111

114-
[!INCLUDE[](~/includes/package-reference.md)]
112+
[!INCLUDE[](~/includes/package-reference.md)]
115113

116-
1. Add a `SKCanvasView` component to the app with the following:
114+
Add a `SKCanvasView` component to the app with the following:
117115

118-
* `SkiaSharp` and `SkiaSharp.Views.Blazor` namespaces.
119-
* Logic to draw in the SkiaSharp Canvas View component (`SKCanvasView`).
116+
* `SkiaSharp` and `SkiaSharp.Views.Blazor` namespaces.
117+
* Logic to draw in the SkiaSharp Canvas View component (`SKCanvasView`).
120118

121-
`Pages/NativeDependencyExample.razor`:
119+
`Pages/NativeDependencyExample.razor`:
122120

123-
```razor
124-
@page "/native-dependency-example"
125-
@using SkiaSharp
126-
@using SkiaSharp.Views.Blazor
121+
```razor
122+
@page "/native-dependency-example"
123+
@using SkiaSharp
124+
@using SkiaSharp.Views.Blazor
127125
128-
<PageTitle>Native dependency</PageTitle>
126+
<PageTitle>Native dependency</PageTitle>
129127
130-
<h1>Native dependency example with SkiaSharp</h1>
128+
<h1>Native dependency example with SkiaSharp</h1>
131129
132-
<SKCanvasView OnPaintSurface="OnPaintSurface" />
130+
<SKCanvasView OnPaintSurface="OnPaintSurface" />
133131
134-
@code {
135-
private void OnPaintSurface(SKPaintSurfaceEventArgs e)
136-
{
137-
var canvas = e.Surface.Canvas;
132+
@code {
133+
private void OnPaintSurface(SKPaintSurfaceEventArgs e)
134+
{
135+
var canvas = e.Surface.Canvas;
138136
139-
canvas.Clear(SKColors.White);
137+
canvas.Clear(SKColors.White);
140138
141-
using var paint = new SKPaint
142-
{
143-
Color = SKColors.Black,
144-
IsAntialias = true,
145-
TextSize = 24
146-
};
139+
using var paint = new SKPaint
140+
{
141+
Color = SKColors.Black,
142+
IsAntialias = true,
143+
TextSize = 24
144+
};
147145
148-
canvas.DrawText("SkiaSharp", 0, 24, paint);
149-
}
150-
}
151-
```
146+
canvas.DrawText("SkiaSharp", 0, 24, paint);
147+
}
148+
}
149+
```
152150

153-
1. Build the app, which might take several minutes. Run the app and navigate to the `NativeDependencyExample` component at `/native-dependency-example`.
151+
Build the app, which might take several minutes. Run the app and navigate to the `NativeDependencyExample` component at `/native-dependency-example`.
154152

155153
## Additional resources
156154

157-
[.NET WebAssembly build tools](xref:blazor/tooling/webassembly)
155+
* [.NET WebAssembly build tools](xref:blazor/tooling/webassembly)
156+
* [Mono/WebAssembly MSBuild properties and targets (`WasmApp.targets`, `dotnet/runtime` GitHub repository)](https://github.com/dotnet/runtime/blob/main/src/mono/wasm/build/WasmApp.Common.targets)

0 commit comments

Comments
 (0)