You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Rust调用接收命令行参数的C++函数报访问错误如何解决

问题根因

你遇到的访问越界错误是参数类型不匹配导致的,核心有两处错误:

  1. FFI函数签名定义错误:C++函数的第二个参数是char *argv[],等价于二级字符指针char**,你在Rust中错误定义为了一级指针*const c_char
  2. 参数构造逻辑错误:你直接将Vec<CString>的指针强制转为一级字符指针传递,不符合C++函数的入参要求
修复方案

1. 修正FFI函数签名

将extern块中的函数定义修改为匹配C++的参数类型:

extern "C" {
    pub fn print_args(args: c_int, argsv: *const *const c_char);
}

2. 修正参数构造逻辑

你需要先构造一个存储所有C字符串指针的数组,再将该数组的指针传递给C++函数,同时注意保留原始CString向量的生命周期避免悬垂指针。修正后的完整main.rs代码如下:

use std::os::raw::{c_int, c_char};
use std::ffi::CString;

extern "C" {
    pub fn print_args(args: c_int, argsv: *const *const c_char);
}

fn main() {
    // 转换命令行参数为CString向量,保留所有权防止提前释放
    let args = std::env::args()
        .map(|arg| CString::new(arg).unwrap())
        .collect::<Vec<CString>>();
    // 构造二级指针数组:存储每个CString的裸指针
    let args_ptr = args.iter()
        .map(|c_str| c_str.as_ptr())
        .collect::<Vec<*const c_char>>();
    let args_len: c_int = args.len() as c_int;
    // 传递二级指针数组的裸指针
    unsafe { print_args(args_len, args_ptr.as_ptr()) };
}
错误原因解释

你之前的写法中,Vec<CString>的as_ptr()返回的是*const CString类型,你强制转为*const c_char传递给C++函数:

  • C++把这个值当成char**解析,第一次解引用拿到的是第一个CString指向的字符串地址,所以可以正常打印出第一个参数
  • 遍历到第二个参数时,C++会偏移一个指针长度(64位系统为8字节)读取下一个char*,此时读取的是第一个字符串的后续内容转成的非法地址,触发访问越界错误。

可选优化

如果要完全符合C的argv规范,可以在构造二级指针数组时末尾追加一个空指针,适配默认需要NULL结尾的C函数:

let mut args_ptr = args.iter()
    .map(|c_str| c_str.as_ptr())
    .collect::<Vec<*const c_char>>();
args_ptr.push(std::ptr::null());

内容的提问来源于stack exchange,提问作者Mai Daly

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.02 03:06:00