首页 > 解决方案 > 从 C 中调用带有函数参数的 Rust 函数会导致 SegFault

问题描述

我用 Rust 构建了一个共享对象并在 C 中链接它。编译/链接工作正常,但是一旦我调用该函数,我就会得到一个 SegFault。

Rust 函数声明:它使用两个整数/usize 和一个对返回整数/usize 的函数的引用。

#[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()与 ac 函数参考不兼容?我用 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

标签: crust

解决方案


&dyn T是一个胖指针(基本上是一个指向数据的指针和一个指向 vtable 的指针),C 对它的内部结构一无所知,所以你需要使用它type Fn = extern "C" fn() -> usize


推荐阅读