如何初始化 sigset_t 或其他在 Rust 中用作“输出参数”的变量?

     2023-02-19     123

关键词:

【中文标题】如何初始化 sigset_t 或其他在 Rust 中用作“输出参数”的变量?【英文标题】:How can I initialize sigset_t or other variables used as "out parameters" in Rust? 【发布时间】:2016-03-26 10:16:08 【问题描述】:

我正在尝试更多地了解 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 中的尝试

use libc; // 0.2.77

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[E0381]: assign to part of possibly-uninitialized variable: `new_action`
 --> src/lib.rs:8:9
  |
8 |         new_action.sa_flags = 0x10000000;
  |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ use of possibly-uninitialized `new_action`

error[E0381]: borrow of possibly-uninitialized variable: `old_action`
  --> src/lib.rs:15:13
   |
15 |             &mut old_action as *mut libc::sigaction,
   |             ^^^^^^^^^^^^^^^ use of possibly-uninitialized `old_action`

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

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

这将不起作用,因为上面的示例中缺少 _restorer,但 _restorer 是私有的。我将如何解决此问题或类似情况?你会使用mem::transmute之类的东西吗?

【问题讨论】:

【参考方案1】:

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

Modern Rust 建议在大多数情况下使用MaybeUninit。应用于您的案例,它看起来像:

use std::mem::MaybeUninit;

let mut new_action: libc::sigaction = MaybeUninit::zeroed().assume_init();
let mut old_action: libc::sigaction = MaybeUninit::zeroed().assume_init();

MaybeUninit 在 Rust 1.36 中稳定。在此之前,您可以使用std::mem::uninitialized(),它会为您提供一个未初始化的值。 LLVM 会认为内容是未定义的,并会在此基础上进行积极的优化。您必须在读取任何值之前对其进行初始化。

更适合您的情况的是std::mem::zeroed(),它为您提供了一个存储空间用零填充的值。这个函数是unsafe,因为这样的值不一定对所有类型都是合法的。 zeroed() 适用于“普通旧数据”(POD)类型。应用于您的案例,它看起来像:

use std::mem;

let mut new_action: libc::sigaction = mem::zeroed();
let mut old_action: libc::sigaction = mem::zeroed();

【讨论】:

【参考方案2】:

使用mem::zeroed怎么样?文档甚至说:

这有时对 FFI 函数很有用,但通常应避免使用。

【讨论】:

rust初始配置

...装Rust在Window7下安装Rust,参考Rust官网上的安装方法,用其他安装Rust的方法中的独立安装程序下的Nightly(1.23)x86_64-p 查看详情

如何在 rust 中迭代 vec 或 slice 的前缀或后缀?

】如何在rust中迭代vec或slice的前缀或后缀?【英文标题】:Howtoiterateprefixesorsuffixesofvecorsliceinrust?【发布时间】:2021-10-2013:36:39【问题描述】:我有一个vec:vec![1,2,3,4]。我想知道如何:从最短到最长迭代它的前缀:&[],&[1],&a... 查看详情

如何确定 Rust 中的 new() 何时在堆栈或堆上分配

】如何确定Rust中的new()何时在堆栈或堆上分配【英文标题】:Howtodeterminewhennew()inRustallocatesonstackorheap【发布时间】:2021-05-3123:04:17【问题描述】:有没有办法(除了查看实现和文档)来确定rust中的new()何时分配到堆栈或堆上?理... 查看详情

Rust:如何在第一个 Err 或 None 上短路退出迭代器方法链?

】Rust:如何在第一个Err或None上短路退出迭代器方法链?【英文标题】:Rust:Howtoshort-circuitexitfromachainofiteratormethodsonfirstErrorNone?【发布时间】:2020-09-0114:01:24【问题描述】:考虑一个迭代器方法链:.iter().a().b().c()其中a产生Option(... 查看详情

如何实现 Rust 的 Copy 特征?

...间】:2016-05-2906:24:34【问题描述】:我正在尝试在Rust中初始化一个结构数组:enumDirectionNorth,East,South,West,structRoadPointdirection:Direction,index:i32,//Initialisethearray,butfailed 查看详情

如何在rust中迭代str或String的前缀和后缀?

】如何在rust中迭代str或String的前缀和后缀?【英文标题】:HowtoiterateprefixesandsuffixesofstrorStringinrust?【发布时间】:2021-10-2100:50:06【问题描述】:我有一个字符串:“abcd”,我想:从最短到最长迭代它的前缀:""、"a"、"ab"、"abc"... 查看详情

如何在 Rust 中惯用地将 bool 转换为 Option 或 Result?

】如何在Rust中惯用地将bool转换为Option或Result?【英文标题】:HowdoIidiomaticallyconvertabooltoanOptionorResultinRust?【发布时间】:2019-07-1709:21:38【问题描述】:使用std似乎没有办法进行这种单行转换。我不喜欢这种冗长:matchmy_booltrue=>... 查看详情

2023年rust发展如何?

1.引言Rust是一种系统编程语言,它注重安全、并发和内存效率。自2010年首次发布以来,Rust一直在快速发展,吸引了越来越多的开发者加入其社区。Rust语言的设计目标是提供一种安全、并发和实用的语言,它可以满足系统编程的... 查看详情

如何“使用”或导入本地 Rust 文件? [复制]

】如何“使用”或导入本地Rust文件?[复制]【英文标题】:HowdoI"use"orimportalocalRustfile?[duplicate]【发布时间】:2021-03-0420:14:20【问题描述】:如何在main.rs中包含具有完整路径my_project/src/include_me.rs的文件?我检查了dependencies... 查看详情

rust-如何在vec上更新或插入?(代码片段)

我正在用Rust编写数据结构。它包含键值对的Vec。当插入结构时,我需要找到一个匹配的键并同时更新键和值(实际上是一个子指针)。代码看起来像这样,其中pivots是refmut的Vec<Pivot>,而Pivot只是具有两个字段的结构... 查看详情

如何在 Rust 中调试内存问题?

】如何在Rust中调试内存问题?【英文标题】:HowdoIdebugamemoryissueinRust?【发布时间】:2016-11-1007:56:27【问题描述】:我希望这个问题不要太开放。我遇到了Rust的内存问题,我得到了an"outofmemory"fromcallingnextonanIteratortraitobject。我不... 查看详情

信号的屏蔽,信号集

...类型sigset_t #include<signal.h>intsigemptyset(sigset_t*set);初始化一个信号集,使其不包括任何信号intsigfillset(sigset_t*set);用来初始化一个信号集,使其包括所有信号intsigaddset(sigset_t*set,intsignum);用来向set指定的信号集 查看详情

在结构中声明 TcpStream 的 Rust 问题

...想尝试编写一个套接字库。我早期遇到的一个问题是如何初始化具有TcpStream的结构structconnectionaddress:String,sock:TcpStream,当我开始时 查看详情

是否可以在 Rust 中返回借用或拥有的类型?

...布时间】:2016-08-1022:13:16【问题描述】:在以下代码中,如何返回floor的引用而不是新对象?是否可以让函数返回借用的引用或拥有的值?externcratenum;//0.2.0usenum::bigint::BigInt;fncal(a:BigInt, 查看详情

如何在 Rust 中打印变量的类型?

】如何在Rust中打印变量的类型?【英文标题】:HowdoIprintthetypeofavariable?【发布时间】:2014-03-1121:53:21【问题描述】:我有以下几点:letmutmy_number=32.90;如何打印my_number的类型?使用type和type_of不起作用。还有其他方法可以打印号... 查看详情

如何在不更改构建系统的情况下在 C 项目中使用 rust 代码?

】如何在不更改构建系统的情况下在C项目中使用rust代码?【英文标题】:HowtouserustcodeinaCprojectwhilenotchangingthebuildsystem?【发布时间】:2019-10-1714:13:08【问题描述】:我试图将nano移植到rust并使用,但我不想更改构建系统或在同一... 查看详情

如何使用rust做静态编译,让编译出来的程序不再依赖其他库?

...如果客户的电脑没有安装相应的依赖,那会运行不了,那如何让RUST程序自带干粮,不依赖这些七七八八的库呢?如果你用的是RUSTGNU版本,那可以直接发给客户,本身就自带了依赖项,不会有问题,本文主要说的是MSVC版本的RUST... 查看详情

C# 如何使用 lambdas 或其他方法使用来自不同列表的值初始化列表 - 需要简化

】C#如何使用lambdas或其他方法使用来自不同列表的值初始化列表-需要简化【英文标题】:C#howtoinitializelistwithvaluesfromdifferentlistusinglambdasorsomethingelse--needtosimplify【发布时间】:2021-10-0900:58:27【问题描述】:我有以下代码,我想对... 查看详情