好的,我将为您翻译以下内容:
- C 调用 Rust
- Rust 回调到 C 并在用户定义的 trait 对象上注册回调函数
- C 通过上下文调用 Rust
- Rust 在上下文(trait 对象)上调用回调函数
我已经进行了一些尝试。虽然我已经做得很多了,但还没有完全成功。
C 部分:
#include <dlfcn.h>
#include <stdio.h>
void *global_ctx;
void c_function(void* ctx) {
printf("Called c_function\n");
global_ctx = ctx;
}
int main(void) {
void *thing = dlopen("thing/target/debug/libthing.dylib", RTLD_NOW | RTLD_GLOBAL);
if (!thing) {
printf("error: %s\n", dlerror());
return 1;
}
void (*rust_function)(void) = dlsym(thing, "rust_function");
void (*rust_cb)(void*) = dlsym(thing, "rust_cb");
printf("rust_function = %p\n", rust_function);
rust_function();
rust_cb(global_ctx);
}
锈蚀位:
extern crate libc;
pub trait Foo {
fn callback(&self);
}
extern {
fn c_function(context: *mut libc::c_void);
}
pub struct MyFoo;
impl Foo for MyFoo {
fn callback(&self) {
println!("callback on trait");
}
}
#[no_mangle]
pub extern fn rust_cb(context: *mut Foo) {
unsafe {
let cb:Box<Foo> = Box::from_raw(context);
cb.callback();
}
}
#[no_mangle]
pub extern fn rust_function() {
println!("Called rust_function");
let tmp = Box::new(MyFoo);
unsafe {
c_function(Box::into_raw(tmp) as *const Foo as *mut libc::c_void);
}
}
问题:
我的程序在尝试在“rust_cb”中对特质对象调用“callback”时崩溃。
一个解决方案: - 将“rust_cb”的函数签名更改为
pub extern fn rust_cb(context: *mut MyFoo)
但这不是我想要的,因为我试图创建一个安全的包装器,只知道侦听器的特征。
希望能得到任何帮助。
PS:我的假设是它会导致段错误,因为编译器不知道 trait Foo 上回调函数的偏移量,它需要实际对象来确定其位置。但我不知道如何解决这个问题。
rust_function
不一定需要是 pub extern,对吗? - Benni