c++11 - 将 C++ 程序移植到 Rust : Of reinterpret_cast, 结构和蓝牙

标签 c++11 struct rust bluez

我有一个静态链接到 libbluetooth/BlueZ 的 C++ 程序,我想将它移植到 Rust 作为练习。

C++ 代码中有一个特别丑陋的地方是通过 read() 从 UNIX 文件描述符中读取数据,然后通过 reinterpret_cast 将生成的缓冲区转换为结构。不幸的是,我不知道如何在 Rust 中实现类似的事情。这个想法是从 libbluetooth 捕获 le_advertising_info 的实例。

C++11 代码:

std::uint8_t buf [HCI_MAX_EVENT_SIZE];
evt_le_meta_event* evt;
le_advertising_info* info;

if (read(_deviceFD, buf, sizeof (buf)) >= HCI_EVENT_HDR_SIZE) {
    evt = reinterpret_cast<evt_le_meta_event*>(buf + HCI_EVENT_HDR_SIZE + 1);
    if (evt != nullptr && evt->subevent == EVT_LE_ADVERTISING_REPORT) {
        void* offset = evt->data + 1;
        for (auto i = 0; i < evt->data [0]; i++) {
            info = reinterpret_cast<le_advertising_info*>(offset);
            if (info != nullptr) {
                if (isBeacon(*info)) {
                    writeLogEntry(*info);
                }
                offset = info->data + info->length + 2;
            }
        }
    }
}

非常感谢有关如何将此位移植到 Rust(以优雅和安全的方式)的一些指示。

最佳答案

在 Rust 中,您可以使用 unsafe std::mem::transmute 函数从一种类型转换为另一种类型,只要它们具有相同的大小。

但是,在您只是从一个指针转换为另一个指针的特定情况下,这甚至不是必需的:您可以只使用 as

struct Hello { a: i32 }
struct World { b: i32 }

fn main() {
    let h = Hello { a: 42 };
    let w = &h as *const Hello as *const World;
    let w: &World = unsafe { &*w };
    println!("{}", w.b);
}

请注意,您需要 unsafe 关键字才能从指针转到引用。 Rust 允许您随意操作指针,但是取消引用指针可能不安全(如果所述指针指向不应该指向的位置)。

由于这最后一步是“门控”的,从引用到指针的转换,或从一种指针类型到另一种指针类型的转换,都是安全的。

与 C 或 C++ 不同,Rust 中没有“严格的别名”规则,因此上述内容是完全安全且合规的。

关于c++11 - 将 C++ 程序移植到 Rust : Of reinterpret_cast, 结构和蓝牙,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42418964/

相关文章:

rest - 为什么warp对于错误键入的参数返回“HTTP 405方法不允许”?

C++将数据从数据文件输入到结构变量中

rust - 为自定义类型实现切片

c++ - 如何使用可变模板参数保存可变数量的参数?

c++ - 是否可以在不锁定或提供 future 的情况下进行查找或创建?

c++ - 具有 vector 成员的全局结构

c - 字节交换结构

rust - 如何修复缺少的生命周期说明符?

c++ - 参数的重载函数(不可)在编译时推导

c++ - 根据谓词从 std vector 中删除元素的有效方法