Passing Vec<> to a c++ lib

Hi

I have a problem passing a vector for my c++ library. Layout goes something like this:

Source tree:

src   - + lib.rs
        |
        + bin - + main.rs
        |
        + ffi - + lt.cpp

In main.rs

use test::*;  // name of my  lib

fn main(){
    
    let mut vv= vec![3i32; 8];

    if wrapper(vv) == true {
        println!("loaded !");
    };
}

in lib.rs :

extern crate libc;

extern "C" {
     pub fn some_c_function(ptr: *mut i32, len: libc::c_int) -> bool;
}

pub fn wrapper(mut a: Vec<i32>) -> bool{
    unsafe {
        some_c_function(a.as_mut_ptr(), a.len() as libc::c_int)
    }
}

in lt.cpp:

bool some_c_function (vector<int> x, int s){
    std::cout << "Vec size: " << x.size()  << " " << s<< std::endl;
    return true;
}

With this setup I get for a result:

Vec size: 0 8
loaded !

But clearly nothing gets through. How to properly pass a vector (and get one back) to a c++ library.

Thank you !

M

A Rust Vec is not the same as a C++ vector. Use raw pointers instead.

2 Likes

Would a small example be too much to ask :blush: :blush: :blush: ?

Sure

// build.rs
extern crate cc;

fn main() {
    cc::Build::new()
        .file("src/sum.c")
        .compile("libsum.a");
}

// src/sum.c
int list_sum(int *input, int len) {
  int sum = 0;
  for (int i = 0; i < len; ++i) {
    sum += input[i];
  }
  return sum;
}

// src/main.rs
extern crate libc;

extern {
    fn list_sum(list: *const libc::c_int, len: libc::c_int) -> libc::c_int;
}

fn main() {
    let list = vec![1, 2, 3, 4, 5, 6];

    let output = unsafe { list_sum(list.as_ptr(), list.len() as libc::c_int) };
    println!("sum({:?}) = {}", list, output);
}

// Cargo.toml
[package]
name = "list-sum"
version = "0.1.0"
authors = ["Alice Ryhl <alice@ryhl.io>"]
build = "build.rs"

[dependencies]
libc = "0.2"

[build-dependencies]
cc = "1.0"
5 Likes

i see where I've gone wrong now ... Thank you so much !!! Thank you !

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.