如何使用 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));
}
代码可以编译,但输出中的无符号整数不正确并且似乎是垃圾,所以我假设这是一个终身问题。我究竟做错了什么?我也尝试使用 MaybeUninit
和 as_mut_ptr
然后使用 std::slice::from_raw_parts
但这有同样的问题。
but the unsigned integers in the output are incorrect and seem to be garbage
如果您不使用 Vec::set_len
,Vec
的长度仍然为零,即使您已经分配了内存并分配了值。如果您打印出 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?
我正在尝试调用一个 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));
}
代码可以编译,但输出中的无符号整数不正确并且似乎是垃圾,所以我假设这是一个终身问题。我究竟做错了什么?我也尝试使用 MaybeUninit
和 as_mut_ptr
然后使用 std::slice::from_raw_parts
但这有同样的问题。
but the unsigned integers in the output are incorrect and seem to be garbage
如果您不使用 Vec::set_len
,Vec
的长度仍然为零,即使您已经分配了内存并分配了值。如果您打印出 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?