【问题标题】:How can I index C arrays in Rust?如何在 Rust 中索引 C 数组?
【发布时间】:2015-01-20 16:31:31
【问题描述】:

我有一个返回指针的 C 函数:

type MYSQL_RES_REF = *mut c_void;
type MYSQL_ROW = *const *const c_char;

#[no_mangle]
extern "C" {
    fn mysql_fetch_row(res: MYSQL_RES_REF) -> MYSQL_ROW;
}

let pointer = mysql_fetch_row(self.res);
let row_p = match pointer {
    p if p == (0 as *const *const c_char) => panic!(),
    p => p,
};

let field: &[u8] = unsafe { ffi::c_str_to_bytes(row_p[i]) };

但尝试对其进行索引(最后一行)会导致错误:

error: cannot index a value of type `*const *const i8`

我想知道std::c_vec是不是我想要的,但apparently that has been removed

【问题讨论】:

  • 注意它不是数组,不要混淆C中的指针和数组,那不是一回事。

标签: arrays rust ffi


【解决方案1】:

有一个offset method on pointers可以用作:

let new_p = p.offset(i);

从当前元素中获取一个指针i 元素。显然,它没有经过边界检查,因此您必须确保它保持在边界内(或过去的一端)。


还有一个不稳定的offset intrinsic

【讨论】:

    【解决方案2】:

    如果你有 C 数组的长度,你可以将指针和长度转换成 Rust 切片,然后使用所有现有的切片支持:

    use libc::size_t; // 0.2.51
    use std::slice;
    
    /// Our opaque C type
    #[repr(C)]
    struct MyCType {
        private: [u8; 0],
    }
    
    extern "C" {
        fn get_ptr_and_len(len: *mut size_t) -> *const MyCType;
        fn do_something_with_type(v: *const MyCType);
    }
    
    fn ptr_and_len() {
        unsafe {
            let mut len = 0;
            let ptr = get_ptr_and_len(&mut len);
    
            let slice = slice::from_raw_parts(ptr, len);
    
            // Indexing
            do_something_with_type(&slice[42]);
    
            // Iteration
            for v in slice {
                do_something_with_type(v);
            }
        }
    }
    

    另见:

    【讨论】:

    • let mut len = 0; 如果值应该被get_ptr_and_len() 替换,那么初始化为零是没有意义的,要么函数返回错误并且len 毫无意义,要么函数被破坏不知何故,init仍然没用。然而,这并没有花费太多,但在一个函数被大量使用的演员阵容中,它可能会告诉 Rust len 将被初始化的方式是什么?因为它“只是”一个整数,所以 应该 很简单。我认为
    • 另外,C 不能有 private: [u8; 0], 字段,所以这可能是一个不好的例子。
    • @Stargateur 这就是你创建不透明类型的方式(因此链接)
    • @Stargateur 无法指定 FFI 代码将初始化长度。在纯 Rust 中,您将返回一个值元组,但使用 FFI 是不可能的。你可以使用mem::uninitialized,但这对于可以廉价归零的类型来说太过分了。
    猜你喜欢
    • 2018-06-25
    • 1970-01-01
    • 2019-05-02
    • 2014-08-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多