[英]Calling Rust function with function parameter from C results in SegFault
我用 Rust 構建了一個共享的 object 並在 C 中鏈接它。 編譯/鏈接工作正常,但只要我調用 function,我就會得到 SegFault。
Rust function 聲明:它使用兩個整數/使用量和對返回整數/使用量的 function 的引用。
#[no_mangle]
pub fn show_loading_animation(from: usize,
to: usize,
progress_in_percentage_fn: &dyn Fn() -> usize) { ... }
我像這樣從 C 調用它:
typedef long long usize; // 64 bit
extern void show_loading_animation(usize, usize, usize (*prog_fn)());
usize progress_reporter() {
return 80l;
}
int main(void) {
show_loading_animation(0, 100, &progress_reporter);
return 0;
}
我假設&dyn Fn()
與 c function 參考不兼容? 我用 gdb 調試了 show_loading_animation。 這是程序集,最后一行是它崩潰的地方。
0000000000004530 <show_loading_animation>:
4530: 55 push %rbp
4531: 41 57 push %r15
4533: 41 56 push %r14
4535: 41 55 push %r13
4537: 41 54 push %r12
4539: 53 push %rbx
453a: 48 81 ec f8 00 00 00 sub $0xf8,%rsp
4541: 48 89 94 24 e0 00 00 mov %rdx,0xe0(%rsp)
4548: 00
4549: 48 89 34 24 mov %rsi,(%rsp)
454d: 48 39 fe cmp %rdi,%rsi
4550: 0f 82 a9 03 00 00 jb 48ff <show_loading_animation+0x3cf>
4556: 48 89 fb mov %rdi,%rbx
4559: 48 8b 41 18 mov 0x18(%rcx),%rax
455d: 48 89 84 24 d8 00 00 mov %rax,0xd8(%rsp)
4564: 00
4565: 45 31 f6 xor %r14d,%r14d
4568: 48 8d 6c 24 30 lea 0x30(%rsp),%rbp
456d: 0f 1f 00 nopl (%rax)
4570: 48 8b bc 24 e0 00 00 mov 0xe0(%rsp),%rdi
4577: 00
4578: ff 94 24 d8 00 00 00 callq *0xd8(%rsp) <-- crash
&dyn T
是一個胖指針(基本上是一個指向數據的指針和一個指向 vtable 的指針),C 對它的內部結構一無所知,所以你需要使用type Fn = extern "C" fn() -> usize
代替。
我可以這樣解決。 我現在提供兩種功能,一種用於rust,一種用於FFI。
// translates extern c function reference to closure function for rust
#[no_mangle]
pub fn show_loading_animation_ffi(from: usize,
to: usize,
progress_in_percentage_fn: extern "C" fn() -> usize) {
let fn_closure = || {
progress_in_percentage_fn()
};
show_loading_animation(from, to, &fn_closure);
}
我從純 rust function 中刪除了#[no_mangle]
(參見上面的代碼)。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.