c - 从 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
解决方案
&dyn T
是一个胖指针(基本上是一个指向数据的指针和一个指向 vtable 的指针),C 对它的内部结构一无所知,所以你需要使用它type Fn = extern "C" fn() -> usize
。
推荐阅读
- random - Arcgis 使用最小允许距离创建随机点
- java - await QueueChannel 如何处理所有消息?
- css - 使用 calc() 动态计算正确的位置
- c++ - libVLC libvlc_media_player 无法打开网络流 (macOS)
- rust - cargo 如何决定是否重建 deps?
- kubernetes - 无法访问 Kubernetes 仪表板
- talend - Talend : 将 JSON 行转换为列,从 JSON 中提取列名
- etl - Snowflake Not Accepting File Format In Bulk Load
- java - 如何配置intellij以查找spring属性源
- cassandra - Datastax java 驱动程序 4.5 tinkerpop 依赖项