【问题标题】:Returning array from c++ to rust in Rust FFI [duplicate]将数组从 C++ 返回到 Rust FFI 中的 rust [重复]
【发布时间】:2018-07-14 10:27:00
【问题描述】:

我有一个用 C++ 编写的函数,该函数将从 Rust 调用。这个函数构造了一个数组并且必须把它返回给 Rust:

ma​​in.rs

extern crate libc;

use libc::c_void;

extern {
    fn construct_array(arr_ptr: *mut u32, arr_size: u32) -> c_void;
}

fn main() {
    let arr_size: usize = 4;
    let mut arr: Vec<u32> = Vec::with_capacity(arr_size);

    unsafe {
        construct_array(arr.as_mut_ptr(), arr_size as u32);
        let result = std::slice::from_raw_parts(arr.as_mut_ptr(), arr_size);
        println!("Result from rust {:?}", result);
    }
}

funcs.cpp

extern "C" void construct_array(uint32_t* arr_ptr, uint32_t arr_size) {
    uint32_t arr[arr_size];

    for (uint32_t i = 0; i < arr_size; i++) {
        arr[i] = i;
    }

    // Print array items
    printf("Result from c++ [");
    printf("%u", arr[0]);
    for (uint32_t i = 1; i < arr_size; i++) {
        printf(", %u", arr[i]);
    }
    printf("]\n");

    arr_ptr = &arr[0];
}

但是,当我运行它时,会打印以下内容:

$ cargo run
Result from c++ [0, 1, 2, 3]
Result from rust [0, 0, 0, 0]

如何在 C++ 中正确构造一个数组并通过 FFI 将其传递给 Rust?

【问题讨论】:

  • construct_array 正在返回一个指向本地自动变量的指针,该指针将在函数完成后立即消失。这将是 C 或 C++ 中的未定义行为。在 Rust 中,它不会轻易编译...

标签: c++ arrays rust ffi


【解决方案1】:

您的问题可以单独在 C++ 中演示:

int main() {
    uint32_t foo[12];
    construct_array(foo, 12);

    printf("Actual result from C++:");
    for (auto i = 0; i < 12; ++i) printf("%u\n", foo[i]);
}

这会打印垃圾,并且来自您“复制”数组的方式:

arr_ptr = &arr[0];

这会将数组的地址分配给局部变量arr_ptr,并且什么也不做。即使这可行,您也会让本地数组的地址转义,那就是 UB。相反,您可以跳过 arr 缓冲区并直接使用传递给您的函数的数组:

extern "C" void construct_array(uint32_t* arr_ptr, uint32_t arr_size) {
    for (uint32_t i = 0; i < arr_size; i++) {
        arr_ptr[i] = i;
    }

    // Print array items
    printf("Result from c++ [");
    printf("%u", arr_ptr[0]);
    for (uint32_t i = 1; i < arr_size; i++) {
        printf(", %u", i);
    }
    printf("]\n");
}

【讨论】:

    猜你喜欢
    • 2019-12-28
    • 2021-10-31
    • 2017-07-18
    • 2019-06-15
    • 1970-01-01
    • 2016-10-19
    • 2021-06-28
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多