I'm trying to call a C function that fills in a vector from Rust. Here is a complete minimal working example:
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));
}
The code compiles, but the unsigned integers in the output are incorrect and seem to be garbage, so I'm assuming it is a lifetime issue. What am I doing wrong? I also tried using MaybeUninit
with as_mut_ptr
then using std::slice::from_raw_parts
but this has the same issue.