I'm trying to pass a vector of vectors buffer from Rust to C adapting an answer on stackoverflow (rust - How do I return an vector of dynamic length in a pub extern "C" fn? - Stack Overflow) for individual vectors. Unfortunately somewhere my mental model of what's going on is obviously wrong and I'm getting a segmentation fault when I try to access the second vector. Can anyone point me in the right direction on how to solve the issue?
I'm new to Rust and only very occasionally dabble in C so apologies if I'm missing something obvious:
lib.rs
#[repr(C)]
pub struct DynArray {
array: *mut *mut i32,
length: libc::size_t,
v_lengths: *mut i32,
}
#[no_mangle]
pub extern "C" fn rust_alloc() -> DynArray {
let mut v: Vec<Vec<i32>> = vec![vec![1, 2, 3], vec![1, 2, 3]];
let mut l: Vec<i32> = vec![3, 3];
let result = DynArray {
array: v.as_mut_ptr() as *mut *mut i32,
length: v.len() as _,
v_lengths: l.as_mut_ptr(),
};
std::mem::forget(v);
std::mem::forget(l);
result
}
#[no_mangle]
pub extern "C" fn rust_free(array: DynArray) {
if !array.array.is_null() {
unsafe {
Box::from_raw(array.array);
}
}
}
main.c
#include <stdio.h>
#include <stdint.h>
struct DynArray {
int32_t** array;
size_t length;
int32_t* v_lengths;
};
struct DynArray rust_alloc();
void rust_free(struct DynArray);
int main () {
struct DynArray vec = rust_alloc();
size_t n = vec.length;
printf("length of containing vector = %d\n", n);
int32_t **values = vec.array;
int32_t *lengths = vec.v_lengths;
for (int i = 0; i < n; i++) {
printf("length of component %d = %d\n",i, lengths[i]);
}
printf("first component entry 0 = %d\n", values[0][0]);
printf("first component entry 1 = %d\n", values[0][1]);
printf("first component entry 2 = %d\n", values[0][2]);
//segfault here
printf("second component entry 0 = %d\n", values[1][0]);
rust_free(vec);
}