https://github.com/openbytedev/netcorehost
A .NET Core hosting library written in Rust with included bindings for nethost and hostfxr.
https://github.com/openbytedev/netcorehost
coreclr dotnet-core hostfxr hosting nethost
Last synced: 5 months ago
JSON representation
A .NET Core hosting library written in Rust with included bindings for nethost and hostfxr.
- Host: GitHub
- URL: https://github.com/openbytedev/netcorehost
- Owner: OpenByteDev
- License: mit
- Created: 2021-03-02T15:15:20.000Z (over 4 years ago)
- Default Branch: master
- Last Pushed: 2025-02-09T15:38:55.000Z (8 months ago)
- Last Synced: 2025-05-14T18:54:56.602Z (5 months ago)
- Topics: coreclr, dotnet-core, hostfxr, hosting, nethost
- Language: Rust
- Homepage:
- Size: 61.3 MB
- Stars: 116
- Watchers: 5
- Forks: 9
- Open Issues: 3
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# netcorehost
[](https://github.com/OpenByteDev/netcorehost/actions/workflows/ci.yml) [](https://crates.io/crates/netcorehost) [](https://docs.rs/netcorehost) [](https://deps.rs/repo/github/openbytedev/netcorehost) [](https://github.com/OpenByteDev/netcorehost/blob/master/LICENSE)
A Rust library for hosting the .NET Core runtime.
It utilizes the .NET Core hosting API to load and execute managed code from withing the current process.
## Usage
### Running an application
The example below will setup the runtime, load `Test.dll` and run its `Main` method:
```rust
let hostfxr = nethost::load_hostfxr().unwrap();
let context = hostfxr.initialize_for_dotnet_command_line(pdcstr!("Test.dll")).unwrap();
let result = context.run_app().value();
```
The full example can be found in [examples/run-app](https://github.com/OpenByteDev/netcorehost/tree/master/examples/run-app).### Calling a managed function
A function pointer to a managed method can be aquired using an [`AssemblyDelegateLoader`](https://docs.rs/netcorehost/*/netcorehost/hostfxr/struct.AssemblyDelegateLoader.html).
This is only supported for [`HostfxrContext`'s](https://docs.rs/netcorehost/*/netcorehost/hostfxr/struct.HostfxrContext.html) that are initialized using [`Hostfxr::initialize_for_runtime_config`](https://docs.rs/netcorehost/*/netcorehost/hostfxr/struct.Hostfxr.html#method.initialize_for_runtime_config). The [`runtimeconfig.json`](https://docs.microsoft.com/en-us/dotnet/core/run-time-config/) is automatically generated for executables, for libraries it is neccessary to add `True` to the projects `.csproj` file.#### Using the default signature
The default method signature is defined as follows:
```csharp
public delegate int ComponentEntryPoint(IntPtr args, int sizeBytes);
```A method with the default signature (see code below) can be loaded using [`AssemblyDelegateLoader::get_function_with_default_signature`](https://docs.rs/netcorehost/*/netcorehost/hostfxr/struct.AssemblyDelegateLoader.html#method.get_function_with_default_signature).
**C#**
```cs
using System;namespace Test {
public static class Program {
public static int Hello(IntPtr args, int sizeBytes) {
Console.WriteLine("Hello from C#!");
return 42;
}
}
}
```**Rust**
```rust
let hostfxr = nethost::load_hostfxr().unwrap();
let context =
hostfxr.initialize_for_runtime_config(pdcstr!("Test.runtimeconfig.json")).unwrap();
let fn_loader =
context.get_delegate_loader_for_assembly(pdcstr!("Test.dll")).unwrap();
let hello = fn_loader.get_function_with_default_signature(
pdcstr!("Test.Program, Test"),
pdcstr!("Hello"),
).unwrap();
let result = unsafe { hello(std::ptr::null(), 0) };
assert_eq!(result, 42);
```#### Using UnmanagedCallersOnly
A function pointer to a method annotated with [`UnmanagedCallersOnly`](https://docs.microsoft.com/en-us/dotnet/api/system.runtime.interopservices.unmanagedcallersonlyattribute) can be loaded without specifying its signature (as these methods cannot be overloaded).**C#**
```cs
using System;
using System.Runtime.InteropServices;namespace Test {
public static class Program {
[UnmanagedCallersOnly]
public static void UnmanagedHello() {
Console.WriteLine("Hello from C#!");
}
}
}
```**Rust**
```rust
let hostfxr = nethost::load_hostfxr().unwrap();
let context =
hostfxr.initialize_for_runtime_config(pdcstr!("Test.runtimeconfig.json")).unwrap();
let fn_loader =
context.get_delegate_loader_for_assembly(pdcstr!("Test.dll")).unwrap();
let hello = fn_loader.get_function_with_unmanaged_callers_only::(
pdcstr!("Test.Program, Test"),
pdcstr!("UnmanagedHello"),
).unwrap();
hello(); // prints "Hello from C#!"
```#### Specifying the delegate type
Another option is to define a custom delegate type and passing its assembly qualified name to [`AssemblyDelegateLoader::get_function`](https://docs.rs/netcorehost/*/netcorehost/hostfxr/struct.AssemblyDelegateLoader.html#method.get_function).**C#**
```cs
using System;namespace Test {
public static class Program {
public delegate void CustomHelloFunc();
public static void CustomHello() {
Console.WriteLine("Hello from C#!");
}
}
}
```**Rust**
```rust
let hostfxr = nethost::load_hostfxr().unwrap();
let context =
hostfxr.initialize_for_runtime_config(pdcstr!("Test.runtimeconfig.json")).unwrap();
let fn_loader =
context.get_delegate_loader_for_assembly(pdcstr!("Test.dll")).unwrap();
let hello = fn_loader.get_function::(
pdcstr!("Test.Program, Test"),
pdcstr!("CustomHello"),
pdcstr!("Test.Program+CustomHelloFunc, Test")
).unwrap();
hello(); // prints "Hello from C#!"
```The full examples can be found in [examples/call-managed-function](https://github.com/OpenByteDev/netcorehost/tree/master/examples/call-managed-function).
### Passing complex parameters
Examples for passing non-primitive parameters can be found in [examples/passing-parameters](https://github.com/OpenByteDev/netcorehost/tree/master/examples/passing-parameters).## Features
- `nethost` - Links against nethost and allows for automatic detection of the hostfxr library.
- `download-nethost` - Automatically downloads the latest nethost binary from [NuGet](https://www.nuget.org/packages/Microsoft.NETCore.DotNetHost/).## Related crates
- [nethost-sys](https://crates.io/crates/nethost-sys) - bindings for the nethost library.
- [hostfxr-sys](https://crates.io/crates/hostfxr-sys) - bindings for the hostfxr library.
- [coreclr-hosting-shared](https://crates.io/crates/coreclr-hosting-shared) - shared bindings between [hostfxr-sys](https://crates.io/crates/hostfxr-sys) and [nethost-sys](https://crates.io/crates/nethost-sys).## Additional Information
- [Hosting layer APIs](https://github.com/dotnet/core-setup/blob/master/Documentation/design-docs/hosting-layer-apis.md)
- [Native hosting](https://github.com/dotnet/core-setup/blob/master/Documentation/design-docs/native-hosting.md#runtime-properties)
- [Write a custom .NET Core host to control the .NET runtime from your native code](https://docs.microsoft.com/en-us/dotnet/core/tutorials/netcore-hosting)## License
Licensed under the MIT license ([LICENSE](https://github.com/OpenByteDev/netcorehost/blob/master/LICENSE) or http://opensource.org/licenses/MIT)