Artem Kolokoltsev
Artem Kolokoltsev

Reputation: 123

What is the best way to convert from a C++ std::vector<float> to a Rust Vec<f32>?

I wrote a test program to check that the data will be read correctly on the Rust.

C++ code:

std::vector<float> vec;
vec.push_back(10);
vec.push_back(20);
std::cout << "len is " << get_len(&vec);

Rust code:

#[no_mangle]
pub extern "C" fn get_len(vec: *const Vec<f32>) -> i32 {
    let vec= unsafe { &*vec};
    vec.len() as i32
}

My output looks like this and is always different:

len is 603268424

Upvotes: 9

Views: 2850

Answers (1)

Stargateur
Stargateur

Reputation: 26727

One thing to know is that C++ doesn't allow giving away the ownership of the data vector. This is a limitation of the C++ design. There are some tricks but I don't advise using them. To stay "safe", you can only borrow a C++ vector.

This can be done easily, using vector::data() and vector::size():

#include <cstddef>
#include <vector>

extern "C" void show_vector(float const *data, std::size_t size);

int main() {
    std::vector<float> vec{10, 20};
    show_vector(vec.data(), vec.size());
}

The Rust side can use slice::from_raw_parts(), creating a view of our vector without taking ownership.

use libc::{c_float, size_t};

extern "C" fn show_vector(data: *const c_float, size: size_t) {
    let vec = unsafe { std::slice::from_raw_parts(data, size) };
    for x in vec {
        println!("{}", x);
    }
}

Read more:

Upvotes: 12

Related Questions