如何在 Rust 中将 char** 转换为 Vec<String>

3

我有一个Rust静态库,它正在链接到一个C项目中。大部分情况下它运行良好。但是我无法弄清如何将一个C char*数组传递给Rust,并使其转换为Rust Vec。

我的C代码:

int rust_main(int argc, char** argv);

int main(int argc, char **argv)
{
    rust_main(argc, argv);
    return 0;
}

我的 Rust 代码:

#[no_mangle]
pub unsafe extern "C" fn rust_main(argc : c_int , argv : &[*mut c_char]) -> c_int {

    let arglen = argc as usize;
    println!("Args: {}", argc);


    for x in 0..arglen {
        let var = CString::from_raw(argv[x]);
        let printable = var.to_string_lossy();
        println!("{}", x);
    }
}

代码编译正常,但是当我尝试访问字符串指针数组时, 发生了核心转储(Core Dump)。

如果有人能指导我正确的方向,我将不胜感激。

2个回答

2
文档中可以看到以下内容:
其他用法(例如尝试占用由外部代码分配的字符串)可能会导致未定义行为或分配器损坏。
注意:如果您需要借用由外部代码分配的字符串,请使用CStr。
您应该调用CStr::from_ptr,然后根据需要使用to_strto_string_lossyinto_c_string将其转换为拥有的值。
#[no_mangle]
pub unsafe extern "C" fn rust_main(argc : c_int , argv : &[*mut c_char]) -> c_int {

    let arglen = argc as usize;
    println!("Args: {}", argc);


    for x in 0..arglen {
        let var = CStr::from_ptr(argv[x]);
        let printable = var.to_string_lossy();
        println!("{}", x);
    }
}

1
argv 让我感到困扰,因为 &[_] 是一个 fat 指针。难道不应该是 *mut *mut c_char 吗? - trent
7
错误的答案,请勿在生产中使用。您无法从 C 代码接受一个切片。 - Stargateur

2
你无法与C代码共享切片(真的没有办法)。
我试图举一个例子,可以将 argv 转换为 String
最初的回答:你不能在C代码中共享切片(真的没有办法)。我尝试制作一个示例,以便将argv转换为 String 。
use libc::{c_char, size_t, c_int};
use std::ffi::CStr;
use std::slice::from_raw_parts;
use std::str::Utf8Error;

pub unsafe fn convert_double_pointer_to_vec(
    data: &mut &mut c_char,
    len: size_t,
) -> Result<Vec<String>, Utf8Error> {
    from_raw_parts(data, len)
        .iter()
        .map(|arg| CStr::from_ptr(*arg).to_str().map(ToString::to_string))
        .collect()
}


#[no_mangle]
pub unsafe extern "C" fn rust_main(argc : c_int , data: &mut &mut c_char) -> c_int {
    let argv = convert_double_pointer_to_vec(data, argc as size_t);

    if let Ok(mut argv) = argv {
        for (i, arg) in argv.iter_mut().enumerate() {
            arg.insert_str(0, &format!("{}: ", i));
        }

        println!("{:#?}", argv);

        0
    }
    else {
        1
    }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接