我正在尝试将 C# 方法传递给 Rust 以用作回调。我已经成功地传递了一个静态函数并且它工作正常(见下文)。
现在我想调用一个实例方法,这意味着trigger下面的函数也应该接收一个不透明的 ( libc::c_void) this 指针。我怎样才能得到哪个IntPtrRust应该作为实例指针传递给回调函数?
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);
}
Run Code Online (Sandbox Code Playgroud)
锈:
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
}
Run Code Online (Sandbox Code Playgroud)
我正在处理相同的代码。我找到了一种比你公开的更简单的方法,看:
\nfn operation(number: i32, f: &dyn Fn(i32) -> i32) {\n f(number);\n}\n#[no_mangle]\nfn print(number: i32) {\n println!("Rust: {}", number);\n}\n#[no_mangle]\npub extern "C" fn c_print(number: i32, callback: unsafe extern "C" fn(i32) -> i32) {\n operation(number, &|n| unsafe { callback(n) });\n}\nRun Code Online (Sandbox Code Playgroud)\n然后,在 C# 中:
\ndelegate void PrintFn(int number);\n\npublic static void Run()\n{\n int number = 1234;\n\n // passing a C# function as parameter of Rust function\n c_print(number, Print);\n\n // passing a Rust function as callback inside the same Rust function\n print(number);\n}\n\nstatic void Print(int number)\n{\n Console.WriteLine($"C#: {number}\\n");\n}\n\n[DllImport(RLIB)] static extern void c_print(int number, PrintFn fn);\n[DllImport(RLIB)] static extern void print(int number);\nRun Code Online (Sandbox Code Playgroud)\n当我开始处理这个问题时,请查找:\xc2\xabHow to use from C# a Rust function that has another function as a argument?\xc2\xbb
\n