gpt4 book ai didi

c# - 将 C# 实例方法作为回调传递给 Rust?

转载 作者:行者123 更新时间:2023-12-05 07:35:01 26 4
gpt4 key购买 nike

我正在尝试将 C# 方法传递给 Rust 以用作回调。我已经设法传递了一个静态函数,它工作正常(见下文)。

现在我想调用一个实例方法,这意味着下面的trigger 函数也应该接收一个不透明的(libc::c_void) this 指针。我怎样才能得到 Rust 应该作为实例指针传递给回调函数的 IntPtr

C#

    class Program
{
delegate void PrintFn(int x);

public static void Main(string[] args)
{
PrintFn fn = Print;
var ptr = Marshal.GetFunctionPointerForDelegate(fn);
IntPtr handle = IntPtr.Zero;
create(ptr, out handle);
trigger(handle, 3);
}

public static void Print(int x)
{
Console.WriteLine($"C#: {x}");
}

[DllImport(@"/path/to/rust/dll")]
public static extern int create(IntPtr readFn, out IntPtr callback);

[DllImport(@"/path/to/rust/dll")]
public static extern int trigger(IntPtr handle, int x);
}

使用rust :

use std::boxed::Box;

pub struct RustCallback {
callback: extern "stdcall" fn(i32),
}

impl RustCallback {
fn new(callback: extern "stdcall" fn(i32)) -> RustCallback {
RustCallback {
callback: read_fn,
}
}
}

pub fn set_output_arg<T>(out: *mut T, value: T) {
unsafe { *out.as_mut().unwrap() = value };
}

#[no_mangle]
pub extern "C" fn create(callback: extern "stdcall" fn(i32), sc: *mut *mut RustCallback) -> u32 {
set_output_arg(sc, Box::into_raw(Box::new(RustCallback::new(callback))));
0
}

#[no_mangle]
pub extern "C" fn trigger(sc: *mut RustCallback, x: i32) -> u32 {
let sc = unsafe { sc.as_mut().unwrap() };
let f = sc.read_fn;
f(x);
0
}

最佳答案

我正在处理相同的代码。我找到了一种比你公开的方法更简单的方法,看:

fn operation(number: i32, f: &dyn Fn(i32) -> i32) {
f(number);
}
#[no_mangle]
fn print(number: i32) {
println!("Rust: {}", number);
}
#[no_mangle]
pub extern "C" fn c_print(number: i32, callback: unsafe extern "C" fn(i32) -> i32) {
operation(number, &|n| unsafe { callback(n) });
}

然后,在 C# 中:

delegate void PrintFn(int number);

public static void Run()
{
int number = 1234;

// passing a C# function as parameter of Rust function
c_print(number, Print);

// passing a Rust function as callback inside the same Rust function
print(number);
}

static void Print(int number)
{
Console.WriteLine($"C#: {number}\n");
}

[DllImport(RLIB)] static extern void c_print(int number, PrintFn fn);
[DllImport(RLIB)] static extern void print(int number);

当我开始处理这个问题时,寻找:«How to use from C# a Rust function that has another function as a parameter?»

关于c# - 将 C# 实例方法作为回调传递给 Rust?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49800598/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com