前情提要:
如何用C#调用RUST的DLL
C#从C/RUST DLL接口获取数组/字符串数据
前面研究过了基础的rust提供dll给C#使用的一些操作,这篇文章就是介绍如何在C#中声明回调函数,提供给rust端来进行调用
基本概念如下:
- 回调函数(C#端编写)
- DLL(Rust编写)
- C#代码调用DLL中的函数,将回调函数作为参数传入,配置回调函数
- 然后再Rust代码中,调用回调函数
rust端代码
rust这边的代码和正常写区别不大,我们假设传入了一个回调函数(fn(i32)
类型),然后单独开一个线程每秒钟触发一次
use std::{thread, time::Duration};
#[no_mangle]
pub extern fn setCb(cb: extern fn(i32)) {
thread::spawn(move || {
let mut count = 0;
loop {
count+=1;
cb(count);
thread::sleep(Duration::from_secs(1));
}
});
}
C#端代码
和之前正常代码的唯一区别就是,需要新建一个独立的回调函数类型,类型声明如下:
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate void DllcallBack(int data);
接着声明dll函数的时候,传入类型用上面声明的类型即可
[DllImport("csharpdll.dll", CallingConvention = CallingConvention.Cdecl)]
static extern void setCb(DllcallBack cb);
最后主代码直接调用
var cb = new DllcallBack((data) => Console.WriteLine($"trigger from rust {data}"));
setCb(cb);
//等待,防止软件运行完退出
Console.ReadLine();
运行效果
正常运行即可查看到预期效果:
trigger from rust 1
trigger from rust 2
trigger from rust 3
trigger from rust 4
trigger from rust 5
trigger from rust 6
...
小改测试回调返回值
可以在c#回调函数中再返回一个结果,看看rust是否可以接收到
use std::{thread, time::Duration};
#[no_mangle]
pub extern fn setCb(cb: extern fn(i32) -> i32) {
thread::spawn(move || {
let mut count = 0;
loop {
count+=1;
let r = cb(count);
println!("rust read cb return: {}", r);
thread::sleep(Duration::from_secs(1));
}
});
}
class Program
{
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate int DllcallBack(int data);
[DllImport("csharpdll/target/debug/csharpdll.dll", CallingConvention = CallingConvention.Cdecl)]
static extern void setCb(DllcallBack cb);
static void Main(string[] args)
{
var cb = new DllcallBack(
(data) =>
{
Console.WriteLine($"trigger from rust {data} * 2 ↓");
return data * 2;
});
setCb(cb);
Console.ReadLine();
}
}
运行结果:
trigger from rust 1 * 2 ↓
rust read cb return: 2
trigger from rust 2 * 2 ↓
rust read cb return: 4
trigger from rust 3 * 2 ↓
rust read cb return: 6
trigger from rust 4 * 2 ↓
rust read cb return: 8
trigger from rust 5 * 2 ↓
rust read cb return: 10
trigger from rust 6 * 2 ↓
rust read cb return: 12