如何在 Rust 中将 char** 转换为 Vec<String>
How to convert char** to Vec<String> in rust
我有一个 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);
}
}
代码编译正常,但是当我尝试访问字符串指针数组时,我得到一个核心转储。
如果有人能指出我正确的方向,将不胜感激。
Other usage (e.g., trying to take ownership of a string that was allocated by foreign code) is likely to lead to undefined behavior or allocator corruption.
Note: If you need to borrow a string that was allocated by foreign code, use CStr.
您应该调用 CStr::from_ptr
,然后根据需要使用 to_str
、to_string_lossy
或 into_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);
}
}
C代码不能共享slice(真的没办法)
我试图举一个例子,将 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
}
}
我有一个 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);
}
}
代码编译正常,但是当我尝试访问字符串指针数组时,我得到一个核心转储。
如果有人能指出我正确的方向,将不胜感激。
Other usage (e.g., trying to take ownership of a string that was allocated by foreign code) is likely to lead to undefined behavior or allocator corruption.
Note: If you need to borrow a string that was allocated by foreign code, use CStr.
您应该调用 CStr::from_ptr
,然后根据需要使用 to_str
、to_string_lossy
或 into_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);
}
}
C代码不能共享slice(真的没办法)
我试图举一个例子,将 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
}
}