Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

Tags:

c++

rust

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
like image 286
Artem Kolokoltsev Avatar asked Jun 06 '19 16:06

Artem Kolokoltsev


People also ask

How do you make a vector in Rust?

In Rust, there are several ways to initialize a vector. In order to initialize a vector via the new() method call, we use the double colon operator: let mut vec = Vec::new();

How do you move a value from one vector to another?

You can't move elements from one vector to another the way you are thinking about; you will always have to erase the element positions from the first vector. If you want to change all the elements from the first vector into the second and vice versa you can use swap. @R.

Is std :: vector fast?

A std::vector can never be faster than an array, as it has (a pointer to the first element of) an array as one of its data members. But the difference in run-time speed is slim and absent in any non-trivial program. One reason for this myth to persist, are examples that compare raw arrays with mis-used std::vectors.

Can you make a vector of different types C++?

“No” C++ is a statically-typed language. A vector will hold an object of a single type, and only a single type.


1 Answers

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:

  • Can I call C or C++ functions from Rust code?
  • How can I get an array or a slice from a raw pointer?
like image 97
Stargateur Avatar answered Oct 31 '22 11:10

Stargateur