簡體   English   中英

如何將Rust`Args`轉換為argc和argv C等價物?

[英]How do I convert Rust `Args` into the argc and argv C equivalents?

我正在使用需要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());
}

通過在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_strto_raw() (例如)失敗。

有沒有人知道如何將Args轉換為更友好的C格式?

我的答案適用於目前穩定的Rust(1.5),可能還有beta和nightly。

下面銹病代碼調用foo(argc, argv)中C.實施的功能的簽名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

證明:

我將此代碼放入貨物項目中,並將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

然后在target/debug/deps下復制libfoo.so (只是在庫搜索路徑中)。 然后我運行我的貨物項目:

$ 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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM