I've been struggling with returning a vec back from my c++ library. The situation is the following:
//rust
fn query (
res: *const libc::c_uchar,
rln: libc::c_ulong
);
...
let result = unsafe{
query(
res.as_mut_ptr(),
rln as libc::c_ulong
);
slice::from_raw_parts(res, rln)
}
//c++
void query ( uchar* res, unsigned long rln) {
rln = 20;
vector<uchar> tres(rln);
for (unsigned long i =0; i< rln; i++){
res[i] = 'x';
}
res = &tres[0];
}
it seams that whenever i use this approach my tres goes out of scope and i am left with blank res vector... What would be the correct way to do this ? (to return a vector from c back to rust)
I suspect you'd be better served by allocating the memory in Rust and then passing a pointer to that memory over FFI to be filled in by the C code. Juggling ownership of collections across FFI is complicated, as you're finding out here.
but what if i cannot know how much memory will i need to pre-allocate... my example is a dummy one just to illustrate a minimum set of requirements... and for some reason i cannot find anything similar on the net... very frustrating, this problem, is
You have to allocate the memory in the same language as where you are going to deallocate it in. Additionally the C++ vector type is not compatible with the Rust Vec type.
You can provide extern Rust functions that allow creation and reallocation of a Rust Vec, and call those from C++ to manage the memory. You can pass the vector to C++ by using the triplet found in the Vec::from_raw_parts method.
Protip: C++ std::vector<T>'s size is vary across platforms. It's 3-ptr-wide on gcc and clang, but 4-ptr-wide on msvc. Oh, and have you heard about the std::vector<bool>?