我正在尝试将一个C#方法传递给Rust以用作回调。 我设法传递一个静态函数,它工作正常(见下文)。
现在我想调用一个实例方法,这意味着下面的trigger
函数也应该接收一个不透明(libc::c_void
)这个指针。
如何获取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);
}
锈:
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
}