如何在Rust中处理指向C字符串数组的三级指针?
问题分析与解决方案
你的核心错误是对char***的指针层级理解有误,对应到Rust的指针操作时层级取反了:
在C++中,name是char***,意味着:
name本身是指向指针数组的指针,数组的每个元素是char**name[i]等价于*(name + i),取到数组里的第i个char***(name[i])才是最终的char*(C风格字符串指针)
而你在Rust代码里直接解引用了name(*(name)),相当于取到了数组的第一个char**,再用它创建切片,相当于从错误的地址开始读取,自然得到乱码。
修正后的代码
use std::os::raw::c_char; use std::ffi::CStr; // 正确获取切片:name是指向*mut *mut c_char数组的指针,直接用它创建切片 // 类型为 &[*mut *mut c_char] let names = unsafe { std::slice::from_raw_parts(name, n) }; for &ptr_ptr in names { // ptr_ptr对应C++里的name[i],解引用得到char* let c_str_ptr = unsafe { *ptr_ptr }; let cs = unsafe { CStr::from_ptr(c_str_ptr) }; println!("{:?}", cs); }
简化写法(等价)
也可以在遍历的时候直接解引用:
use std::os::raw::c_char; use std::ffi::CStr; let names = unsafe { std::slice::from_raw_parts(name, n) }; for ptr_ptr in names { let c_str_ptr = unsafe { **ptr_ptr }; let cs = unsafe { CStr::from_ptr(c_str_ptr) }; println!("{:?}", cs); }
关键说明
- 原代码中
std::slice::from_raw_parts(*(name), n)是错误的:*(name)是*mut *mut c_char,用它作为切片起始地址,相当于读取name[0]指向的内存区域,而非name指向的数组。 - 修正后用
name直接创建切片,对应C++中遍历name指向的指针数组,每个元素是char**,再解引用一次得到真正的字符串指针。
内容的提问来源于stack exchange,提问作者yesint
相关产品推荐
相关产品推荐

