如何使用 C 函数填充未初始化的 Rust 向量?

How can I fill an uninitialized Rust vector using a C function?

我正在尝试调用一个 C 函数来填充来自 Rust 的向量。这是一个完整的最小工作示例:

Cargo.toml

[package]
name = "so"
version = "0.1.0"
edition = "2021"

[build-dependencies]
cc = "1.0.72"

build.rs

fn main() {
    cc::Build::new().file("src/library.c").compile("library");
}

src/library.c

void get_ui_array(unsigned long *out, long len) {
  long i;
  for (i = 0; i < len; i++) {
    out[i] = 42;
  }
}

src/main.rs

use std::os::raw::{c_long, c_ulong};

extern "C" {
    pub fn get_ui_array(out: *mut c_ulong, len: c_long);
}

fn get_ui_vector(len: c_long) -> Vec<c_ulong> {
    let mut out = Vec::<c_ulong>::with_capacity(len as usize);
    unsafe {
        get_ui_array(out.as_mut_ptr(), len);
    }
    out
}

fn main() {
    dbg!(get_ui_vector(12));
}

代码可以编译,但输出中的无符号整数不正确并且似乎是垃圾,所以我假设这是一个终身问题。我究竟做错了什么?我也尝试使用 MaybeUninitas_mut_ptr 然后使用 std::slice::from_raw_parts 但这有同样的问题。

but the unsigned integers in the output are incorrect and seem to be garbage

如果您不使用 Vec::set_lenVec 的长度仍然为零,即使您已经分配了内存并分配了值。如果您打印出 Vec,它将是空的,所以我想知道您如何在输出中看到 any 个整数。

也就是说,使用 set_len 应该可以解决问题:

fn get_ui_vector(len: c_long) -> Vec<c_ulong> {
    let mut out = Vec::<c_ulong>::with_capacity(len as usize);
    unsafe {
        get_ui_array(out.as_mut_ptr(), len);
        out.set_len(len as usize); // HERE
    }
    out
}

I assumed with_capacity was setting the length (I'm still not sure why it doesn't).

设置向量的容量时,不会在向量中设置任何。如果未设置值,访问它们将导致未定义的行为。

如果你想定义值,你可以使用像 Vec::resize.

这样的东西

另请参阅:

  • How to allocate space for a Vec<T> in Rust?