31 个不稳定版本

0.17.0 2024年2月2日
0.15.1 2023年8月11日
0.15.0 2023年7月31日
0.13.1 2022年11月29日
0.1.0 2021年3月4日

#17 in Windows API

Download history 112/week @ 2024-03-13 43/week @ 2024-03-20 20/week @ 2024-03-27 62/week @ 2024-04-03 65/week @ 2024-04-10 49/week @ 2024-04-17 33/week @ 2024-04-24 57/week @ 2024-05-01 5/week @ 2024-05-08 20/week @ 2024-05-15 77/week @ 2024-05-22 42/week @ 2024-05-29 57/week @ 2024-06-05 79/week @ 2024-06-12 129/week @ 2024-06-19 114/week @ 2024-06-26

385 每月下载量
4 个crate中使用 (2 直接)

MIT 许可

170KB
2.5K SLoC

netcorehost

CI crates.io Documentation dependency status MIT

用于托管 .NET Core 运行时的 Rust 库。

它使用 .NET Core 托管 API 在当前进程中加载和执行托管代码。

用法

运行应用程序

以下示例将设置运行时,加载 Test.dll 并运行其 Main 方法

let hostfxr = nethost::load_hostfxr().unwrap();
let context = hostfxr.initialize_for_dotnet_command_line(pdcstr!("Test.dll")).unwrap();
let result = context.run_app().value();

完整的示例可以在 examples/run-app 中找到。

调用托管函数

可以使用 AssemblyDelegateLoader 获取指向托管方法的函数指针。这仅支持使用 HostfxrContext's 初始化的方法。对于可执行文件,runtimeconfig.json 会自动生成;对于库,需要在项目的 .csproj 文件中添加 <GenerateRuntimeConfigurationFiles>True</GenerateRuntimeConfigurationFiles>

使用默认签名

默认方法签名如下定义

public delegate int ComponentEntryPoint(IntPtr args, int sizeBytes);

可以使用 AssemblyDelegateLoader::get_function_with_default_signature 加载具有默认签名的方 法(如下面的代码所示)。

C#

using System;

namespace Test {
    public static class Program {
        public static int Hello(IntPtr args, int sizeBytes) {
            Console.WriteLine("Hello from C#!");
            return 42;
        }
    }
}

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);

使用 UnmanagedCallersOnly

指向带有UnmanagedCallersOnly注解的方法的函数指针可以在不指定其签名的情况下加载(因为这些方法不能重载)。

C#

using System;
using System.Runtime.InteropServices;

namespace Test {
    public static class Program {
        [UnmanagedCallersOnly]
        public static void UnmanagedHello() {
            Console.WriteLine("Hello from C#!");
        }
    }
}

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::<fn()>(
    pdcstr!("Test.Program, Test"),
    pdcstr!("UnmanagedHello"),
).unwrap();
hello(); // prints "Hello from C#!"

指定委托类型

另一种选择是定义一个自定义委托类型,并将其实例的完全限定名传递给AssemblyDelegateLoader::get_function

C#

using System;

namespace Test {
    public static class Program {
        public delegate void CustomHelloFunc();
    
        public static void CustomHello() {
            Console.WriteLine("Hello from C#!");
        }
    }
}

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::<fn()>(
    pdcstr!("Test.Program, Test"),
    pdcstr!("CustomHello"),
    pdcstr!("Test.Program+CustomHelloFunc, Test")
).unwrap();
hello(); // prints "Hello from C#!"

完整示例可以在examples/call-managed-function中找到。

传递复杂参数

有关传递非原始参数的示例,请参阅examples/passing-parameters

功能

  • nethost - 链接到nethost并允许自动检测hostfxr库。
  • download-nethost - 从NuGet自动下载最新的nethost二进制文件。

其他信息

许可

在MIT许可下授权(LICENSEhttp://opensource.org/licenses/MIT

依赖项

~0.6–2.6MB
~39K SLoC