|
1 | 1 | # Component wire format |
2 | 2 |
|
3 | 3 | Bindings generated from WIT exchange values in this format. It is used by |
4 | | -`host_bindgen!`, `guest_bindgen!` and the hyperlight-wasm guest runtime. The |
5 | | -host and guest must be built from the same Hyperlight version. |
| 4 | +`host_bindgen!`, `guest_bindgen!`, the hyperlight-wasm guest runtime, and the |
| 5 | +C# generator in `hyperlight-component-csharp`. The host and guest must be built |
| 6 | +from the same Hyperlight version. |
6 | 7 |
|
7 | 8 | ## Calls |
8 | 9 |
|
@@ -49,3 +50,47 @@ their parts with no alignment. |
49 | 50 | lists encodings of the types in |
50 | 51 | [`wire.wit`](../src/tests/component_wire/wire.wit). The Rust host bindings are |
51 | 52 | tested against it. |
| 53 | + |
| 54 | +## C# host bindings |
| 55 | + |
| 56 | +`hyperlight_component_csharp::generate_from_path` generates C# for the host |
| 57 | +side of a world. The generated code depends on the `Hyperlight.Component` |
| 58 | +namespace in `hyperlight_component_csharp::RUNTIME_SOURCE`. It targets .NET 8 |
| 59 | +or later. |
| 60 | + |
| 61 | +For a world `w`, the generator emits: |
| 62 | + |
| 63 | +* `WComponent`, constructed from an `IGuestCaller`. It has a property for each |
| 64 | + exported interface and a method for each function the world exports. |
| 65 | +* `WComponent.RegisterImports`, which registers host functions on an |
| 66 | + `IHostFunctionRegistry` from an implementation of each imported interface. |
| 67 | +* A C# interface `IName` for each imported interface `name`, and `IWImports` |
| 68 | + for functions the world imports. |
| 69 | +* Types for every record, variant, enum and flags in the world's interfaces. |
| 70 | + |
| 71 | +| WIT type | C# type | |
| 72 | +|---|---| |
| 73 | +| `bool`, integers, floats | `bool`, `sbyte` to `ulong`, `float`, `double` | |
| 74 | +| `char` | `System.Text.Rune` | |
| 75 | +| `string` | `string` | |
| 76 | +| `list<u8>`, `list<u8, N>` | `byte[]` | |
| 77 | +| `list<T>`, `list<T, N>` | `IReadOnlyList<T>` | |
| 78 | +| `tuple<...>` | Value tuple | |
| 79 | +| `option<T>` | `T?`, or `Option<T>` when `T` is an `option` | |
| 80 | +| `result<T, E>` | `Result<T, E>`, with `Unit` for a missing type | |
| 81 | +| `record` | Sealed record with `required init` properties | |
| 82 | +| `variant` | Abstract record with a nested sealed record per case | |
| 83 | +| `enum` | `enum` with `uint` values | |
| 84 | +| `flags` | `[Flags]` enum with `uint` values | |
| 85 | + |
| 86 | +Resources, async functions, futures, streams, maps and flags with more than 32 |
| 87 | +members are rejected. |
| 88 | + |
| 89 | +Records, variant cases, `Option` and `Result` compare lists by element. |
| 90 | +Variants and `Result` have `Match` and `Switch` methods that take one function |
| 91 | +per case. These give a compile error when a case is missing. |
| 92 | + |
| 93 | +For a root namespace `Root`, types from `ns:pkg/iface` are in |
| 94 | +`Root.Ns.Pkg.Iface`. The C# interface or exports class for `iface` is in |
| 95 | +`Root.Ns.Pkg`. A world that uses two versions of a package gets the version |
| 96 | +after `Pkg`, such as `Root.Ns.Pkg.V1_0_0`. |
0 commit comments