首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何将Rust ` argv‘转换为argc和argc等价物?

如何将Rust ` argv‘转换为argc和argc等价物?
EN

Stack Overflow用户
提问于 2015-12-20 09:36:46
回答 1查看 3.4K关注 0票数 6

我正在使用一个C(特别是MPI_Init),它需要int argc, char **argv。我试图用以下代码生成一个等价的argc, argv

代码语言:javascript
复制
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());
}

通过调整论吉突布

它失败了,因为:

代码语言:javascript
复制
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_strto_raw() (例如)失败了。

有没有人知道如何将Args转换成C友好的格式?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2015-12-20 10:17:12

我的答案适用于当前稳定的锈菌(1.5)和可能的测试版和夜间版。

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

代码语言:javascript
复制
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()

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

证明:

我将这些代码放入一个货运项目中,并添加了libc作为一个依赖项。foo()函数如下所示:

代码语言:javascript
复制
#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]);
    }
}

我用以下方法编译了这个代码:

代码语言:javascript
复制
gcc foo.c -o libfoo.so -shared -fPIC

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

代码语言:javascript
复制
$ 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
票数 10
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/34379641

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档