在Rust中初始化sigset_t

我正在尝试更多地了解Rust中的FFI以及与C库(特别是libc )的链接。 在我的“任务”中,我遇到了以下问题。

C中的正常模式

 void(* sig_set(int sig, void(*handler)(int))) { // uninitialized sigaction structs struct sigaction new_action, old_action; // assign options to new action new_action.sa_flags = SA_RESTART; new_action.sa_handler = handler; sigemptyset(&new_action.sa_mask); if(sigaction(sig, &new_action, &old_action) < 0) { fprintf(stderr, "Error: %s!\n", "signal error"); exit(1); } return old_action.sa_handler; } 

在Rust中尝试

 fn sig_init(sig: i32, handler: fn(i32)->()) -> usize { unsafe { let mut new_action: libc::sigaction; let mut old_action: libc::sigaction; new_action.sa_flags = 0x10000000; new_action.sa_sigaction = handler as usize; libc::sigemptyset(&mut new_action.sa_mask as *mut libc::sigset_t); libc::sigaction( sig, &mut new_action as *mut libc::sigaction, &mut old_action as *mut libc::sigaction ); old_action.sa_sigaction } } 

当我尝试上述操作时,编译器将抛出以下错误以使用可能未初始化的变量。

 error: use of possibly uninitialized variable: `` [E0381] 

这是有道理的,因为如果从sa_mask读取sa_mask可能会发生非常糟糕的事情。 所以我在上面的第3行尝试了以下内容。

 let mut new_action: libc::sigaction = libc::sigaction{ sa_sigaction: handler as usize, sa_flags: 0x10000000, sa_mask: mask, }; 

这不起作用,因为上面的例子中缺少_restorer ,但_restorer是私有的。 那么如何解决这个问题或一个相似的情况呢? 你会使用像mem::transmute这样的东西吗?

标准库定义了几个处理初始化的函数。 它们是通用的,因此可用于初始化任何类型的值。

首先,有std::mem::uninitialized() ,它给你一个未初始化的值。 LLVM将认为内容未定义,并将基于此执行积极的优化。 您必须在读取之前初始化任何值。

其次,有std::mem::zeroed() ,它为你提供一个存储用零填充的值。 此functionunsafe因为这样的值对于所有类型都不一定合法。 zeroed()适用于“普通旧数据”(POD)类型。

如何使用mem::zeroed ? 文档( https://doc.rust-lang.org/std/mem/fn.zeroed.html )甚至说:

这有时对FFIfunction很有用,但通常应该避免。