gpt4 book ai didi

enums - 如何将 bindgen 生成的 C 风格枚举转换为另一个枚举?

转载 作者:行者123 更新时间:2023-12-03 11:27:15 24 4
gpt4 key购买 nike

我在 Rust 中为 C 库和 Bindgen 生成的枚举创建绑定(bind),例如:

// Rust
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
pub enum rmw_qos_history_policy_t {
RMW_QOS_POLICY_HISTORY_SYSTEM_DEFAULT = 0,
RMW_QOS_POLICY_HISTORY_KEEP_LAST = 1,
RMW_QOS_POLICY_HISTORY_KEEP_ALL = 2,
RMW_QOS_POLICY_HISTORY_UNKNOWN = 3,
}

我需要将它们转换为:

// Rust
pub enum QoSHistoryPolicy {
SystemDefault = 0,
KeepLast = 1,
KeepAll = 2,
Unknown = 3,
}

从这个 C 库导入常量值时:

// C library
const rmw_qos_history_policy_t some_value_from_C = RMW_QOS_POLICY_HISTORY_SYSTEM_DEFAULT;

我想做这样的事情:

let some_value: QoSHistoryPolicy = some_value_from_C;

我该怎么做?

最佳答案

编译器不检查枚举的 ABI 兼容性,因此不提供在这些类型之间转换值的直接方法。以下是一些可能的解决方案。

1。一对一匹配

这是微不足道且安全的,尽管会导致详尽的代码。

impl From<rmw_qos_history_policy_t> for QoSHistoryPolicy {
fn from(x: rmw_qos_history_policy_t) -> Self {
use rmw_qos_history_policy_t::*;
match x {
RMW_QOS_POLICY_HISTORY_SYSTEM_DEFAULT => QoSHistoryPolicy::SystemDefault,
RMW_QOS_POLICY_HISTORY_KEEP_LAST => QoSHistoryPolicy::KeepLast,
RMW_QOS_POLICY_HISTORY_KEEP_ALL => QoSHistoryPolicy::KeepAll,
RMW_QOS_POLICY_HISTORY_UNKNOWN => QoSHistoryPolicy::Unknown,
}
}
}

2。类型转换 + FromPrimitive

Rust 允许您使用 as 运算符将无字段枚举转换为整数类型。然而,相反的转换并不总是安全的。使用 num crate 派生 FromPrimitive 以获得丢失的部分。

#[derive(FromPrimitive)]
pub enum QoSHistoryPolicy { ... }

impl From<rmw_qos_history_policy_t> for QoSHistoryPolicy {
fn from(x: rmw_qos_history_policy_t) -> Self {
FromPrimitive::from_u32(x as _).expect("1:1 enum variant matching, all good")
}
}

3。需要一个枚举?

如果您只想对低级绑定(bind)进行抽象,则可能不需要新的枚举类型。

#[repr(transparent)]
pub struct QoSHistoryPolicy(rmw_qos_history_policy_t);

上面的类型包含相同的信息和二进制表示,但可以公开封装的 API。从低级类型到高级类型的转换变得微不足道。主要缺点是您失去了与其变体的模式匹配。

4。你一个人

绝对确定这两个枚举的二进制表示形式相同时,您可以在它们之间转换。编译器不会在这里帮助你,这远非推荐。

unsafe {
let policy: QoSHistoryPolicy = std::mem::transmute(val);
}

另请参阅:

关于enums - 如何将 bindgen 生成的 C 风格枚举转换为另一个枚举?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60738357/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com