生锈 – 如果在不包含不安全功能的情况下预期安全功能,我如何传递不安全的功能?

我想将pthread_create指向我后来链接到的C函数.该C函数将使用pthread_cleanup_push和pthread_cleanup_pop这些是C宏,因此无法移植到Rust.

这是我的代码:

extern crate libc;
use std::ptr::null_mut;
use libc::c_void;

extern "C" {
    fn thr_fn1(arg:*mut c_void) -> *mut c_void;
}

fn main() {
    let mut tid1 = std::mem::zeroed();
    libc::pthread_create(&mut tid1, null_mut(), thr_fn1, null_mut());
}

我预计,因为我正在调用libc的FFI,我只能指向一个外部C函数,但是我收到一个错误:

error[E0308]: mismatched types
  --> src/bin/11-threads/f05-thread-cleanup.rs:25:49
   |
25 |     libc::pthread_create(&mut tid1, null_mut(), thr_fn1, null_mut());
   |                                                 ^^^^^^^ expected normal fn, found unsafe fn
   |
   = note: expected type `extern "C" fn(*mut libc::c_void) -> *mut libc::c_void`
              found type `unsafe extern "C" fn(*mut libc::c_void) -> *mut libc::c_void {thr_fn1}`

我可以编写一个在不安全的{}块中调用C函数的包装器,但是有什么办法可以避免这种情况吗?

最佳答案 libc函数定义错误:C头文件/usr/include/pthread.h:

extern int pthread_create (pthread_t *__restrict __newthread,
                           const pthread_attr_t *__restrict __attr,
                           void *(*__start_routine) (void *),
                           void *__restrict __arg) __THROWNL __nonnull ((1, 3));

bindgen生成此函数定义:

pub fn pthread_create(arg1: *mut pthread_t,
                      arg2: *const pthread_attr_t,
                      arg3: Option<unsafe extern "C" fn(arg1: *mut c_void) -> *mut c_void>,
                      arg4: *mut c_void) -> c_int;

哪个在macOS和Linux上编译.我不确定Option在这里是个好主意;为什么有人会启动一个不调用函数的线程?

我打开a PR for libc来纠正问题(没有选项部分)

点赞