gpt4 book ai didi

c - 如何将 Rust `Args` 转换为 argc 和 argv C 等价物?

转载 作者:太空狗 更新时间:2023-10-29 16:11:07 25 4
gpt4 key购买 nike

我正在使用需要 int argc, char **argv 的 C API(特别是 MPI_Init)。我正在尝试使用以下代码生成等效的 argc, argv:

let argc = std::env::args().len() as c_int;
let c_strs: ~[CString] = std::env:args().map(|s: & &str| s.to_c_str());
let mut argv: ~[*c_char] = c_strs.map(|c: &CString| c.with_ref(|ptr| ptr));
if null_terminate {
argv.push(std::ptr::null());
}

通过改编this discussion on Github .

它失败了:

error: expected type, found `~`
src/lib.rs:37 let c_strs: ~[CString] = std::env::args().map(|s: & &str| s.to_c_str());
^

我摆脱了 ~ 然后它找不到 to_c_str() 并且不确定用什么替换 to_c_str to_raw()(例如)失败。

有谁知道将 Args 转换为对 C 更友好的格式的方法吗?

最佳答案

我的答案适用于当前稳定的 Rust (1.5),并且可能适用于 beta 和 nightly。

下面的 Rust 代码调用了用 C 实现的 foo(argc, argv) 函数。foo 的签名非常类似于 main 功能。

extern crate libc;

use libc::c_char;
use libc::c_int;

use std::ffi::CString;

#[link(name="foo")]
extern "C" {
fn foo(argc: c_int, argv: *const *const c_char);
}

fn main() {
// create a vector of zero terminated strings
let args = std::env::args().map(|arg| CString::new(arg).unwrap() ).collect::<Vec<CString>>();
// convert the strings to raw pointers
let c_args = args.iter().map(|arg| arg.as_ptr()).collect::<Vec<*const c_char>>();
unsafe {
// pass the pointer of the vector's internal buffer to a C function
foo(c_args.len() as c_int, c_args.as_ptr());
};
}

请注意,C 端只是借用 指向字符串的指针。如果要存储它们,请对它们使用 strdup()

我还在 CString 实例上使用了 unwrap()。如果您的字符串包含 0 个字节,它将返回错误,请参阅 https://doc.rust-lang.org/stable/std/ffi/struct.CString.html#method.new .

证明:

我把这段代码放到了一个 cargo 项目中,并添加了 libc 作为依赖。foo() 函数如下所示:

#include <stdio.h>

void foo(int argc, char* argv[]) {
int i;

for (i = 0; i < argc; i++) {
printf("argv[%d]: %s\n", i, argv[i]);
}
}

我用以下代码编译了这段代码:

gcc foo.c -o libfoo.so -shared -fPIC

然后将 libfoo.so 复制到 target/debug/deps 下(只是为了在库搜索路径中)。然后我运行我的 cargo 项目:

$ cargo run the quick brown fox
Compiling args v0.1.0 (file:///home/tibi/Codes/Rust/argv/args)
Running `target/debug/args the quick brown fox`
argv[0]: target/debug/args
argv[1]: the
argv[2]: quick
argv[3]: brown
argv[4]: fox

关于c - 如何将 Rust `Args` 转换为 argc 和 argv C 等价物?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34379641/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com