当前位置: 首页 > 知识库问答 >
问题:

如何正确地填充C字符串指针?

贺季
2023-03-14

我有一个外国金融机构签名,我需要执行:

pub unsafe extern fn f(header_size: u32, header_ptr: *mut u8) -> i32;

FFI调用者需要提供一个缓冲区header\u ptr和该缓冲区的大小header\u size。Rust将向该缓冲区中填充一个字符串,最大值为标题大小,如果成功,则返回0。FFI调用方应将字符串解释为ASCII。

鉴于我有一个头,我如何以最惯用的方式填充缓冲区:

现在我有:

let header_bytes = slice::from_raw_parts_mut(header_ptr, header_size as usize);

if header_bytes.len() < headers.len() { return Errors::IndexOutOfBounds as i32; }

for (i, byte) in headers.as_bytes().iter().enumerate() {
    header_bytes[i] = *byte;
}

但这感觉不对。

编辑,我认为这不是一个完全重复的问题,因为我的问题与字符串有关,而IIRC在转换时有特殊的考虑


共有1个答案

陈翰林
2023-03-14

由于C字符串不超过0终止字节数组,从Rust字符串转换是非常直接的。几乎每个有效的Rust字符串也是一个有效的C字符串,但是您必须确保C字符串以0字符结束,并且字符串中的其他任何地方都没有0字符。

Rust提供了一个负责转换的类型:CString

如果您的输入字符串成功地转换为CString,您可以简单地复制字节,而无需担心细节。

use std::slice;
use std::ffi::CString;

pub unsafe extern fn f(header_size: u32, header_ptr: *mut u8) -> i32 {
    let headers = "abc";
    let c_headers = match CString::new(headers) {
        Ok(cs) => cs,
        Err(_) => return -1,  // failed to convert to C string
    };
    let bytes = c_headers.as_bytes_with_nul();

    let header_bytes = slice::from_raw_parts_mut(header_ptr, header_size as usize);
    header_bytes[..bytes.len()].copy_from_slice(bytes);

    0  // success
}

fn main() {
    let mut h = [1u8; 8];

    unsafe {
        f(h.len() as u32, h.as_mut_ptr());
    }

    println!("{:?}", h);  // [97, 98, 99, 0, 1, 1, 1, 1]
}

请注意,为了简洁起见,我省略了长度检查。header_bytes[...bytes.len()]将在缓冲区太短时感到恐慌。如果从C调用f,则需要避免这种情况。

 类似资料:
  • 老师们好: C 语言实现, 给定一个字符串长度不是16字节倍数时,请将字符串左边用0填充,使其长度为16字节的整倍数。 期望得到下面给出的结果

  • 问题内容: 有一些简单的方法可以在Java中填充字符串吗? 似乎应该在类似StringUtil的API中使用某些东西,但是我找不到能做到这一点的任何东西。 问题答案: 有几种方法:leftPad,[rightPad](https://commons.apache.org/proper/commons-lang/javadocs/api-2.6/org/apache/commons/lang/Str

  • 我正在创建一个战舰游戏应用程序来学习OOP,Java。我想显示一个“空海”供玩家参考放置他们的舰队。下面是我的游戏板课的开始: 我把这叫做主要的:

  • 我正在尝试使用下面列出的代码使用SSL侦听器端口访问db。 但我看到下面的错误。我也尝试使用“setproperty”更新用户id和passowrd,但仍然看到相同的错误。

  • 假设我有一个整数数组,如和一个简单的字符串,如。我如何循环通过数组和填充每一个值。假设是这样的: 输出: 到目前为止,我已经尝试了以下内容: 但是,它在print语句中给出了。解决这个问题最好的方法是什么?