簡體   English   中英

調用 Rust function 與 function 參數從 S0D61F8370CAD1D412F80B84D4Dault 結果

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM