如何从 Str 获取 *mut c_char?

How do I get a *mut c_char from a Str?

为了能够使用 C 库,我需要给函数一个 *mut c_char 参数。但是我找不到从 str.

获取它的方法

我将我的 str 转换为 CString, that's ok, but there's no more way from CString to get a *mut c_char in the nightly build. I found that in 0.12.0 there was a method,但是现在,获取 *mut c_char 的过程是什么?

查看 this piece of documentationfn as_mut_ptr() 已移至 API 的 slice 部分。所以你需要一个 &mut [c_char] 类型的可变切片。而且据我所知,您无法从 CString 中获取它,它们将是只读的。

您可以使用 mut Vec<c_char>:

let mut x : Vec<c_char> = ...;
let slice = x.as_mut_slice();
let ptr = slice.as_mut_ptr();

感谢 rodrigo 的 post,我找到了解决问题的方法(很脏,但有效)。这是代码:

let mut string = std::string::String::from_str("Test");
let bytes = string.into_bytes();
let mut cchar : Vec<c_char> = bytes.map_in_place(|w| w as c_char);
let slice = cchar.as_mut_slice();
let name: *mut c_char = slice.as_mut_ptr();

我觉得有点复杂

let bytes = String::from_str("Test").into_bytes() + b"[=10=]";
let cchars = bytes.map_in_place(|b| b as c_char);
let name: *mut c_char = cchars.as_mut_ptr();

基本思路和你的一样,但是不需要显式地切分Vec;还将一个零字节附加到缓冲区。另请参阅我对问题的评论。

五年后 none 这些解决方案正在发挥作用(至少对我而言)。

的略微修改版本:

let string: &str = "Hello, world!";
let bytes: Vec<u8> = String::from(string).into_bytes();
let mut c_chars: Vec<i8> = bytes.iter().map(| c | *c as i8).collect::<Vec<i8>>();

c_chars.push(0); // null terminator

let ptr: *mut c_char = c_chars.as_mut_ptr();

如果你想

let mut hello =   b"Hello World[=10=]".to_vec().as_mut_ptr() as *mut i8;

现在(2022 年),into_raw() 很适合我,例如:

use std::ffi::CString;
use std::os::raw::c_char;
fn main() {    
  let c_string = CString::new("Hello!").expect("CString::new failed");
  let raw: *mut c_char = c_string.into_raw();
}

查看 https://doc.rust-lang.org/std/ffi/struct.CString.html#method.into_raw 了解更多信息。