我想将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}`
我可以编写一个在unsafe{}
块中调用C函数的包装器,但是有什么方法可以避免这种情况吗?
答案 0 :(得分:1)
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
来解决问题(没有Option
部分)