我想在Rust程序中使用命令行參數並將它們傳遞給C函數。但是,這些參數是可選的,如果沒有參數提供,程序應該有不同的表現。我已閱讀CString::as_ptr
的文檔,但我希望保留一個包含參數Option
的本地變量(如果存在的話)將保持String
不被釋放,如下例所示。是否有更自然的方式來保持可選參數字符串被釋放?
此拉斯特代碼:
extern crate libc;
use std::ffi::CString;
extern "C" {
fn print_in_c(opt_class: *const libc::c_char) -> libc::c_int;
}
fn main() {
let mut args = std::env::args();
//skip execuatble name
args.next();
let possible_arg = args.next();
println!("{:?}", possible_arg);
let arg_ptr = match possible_arg {
Some(arg) => CString::new(arg).unwrap().as_ptr(),
None => std::ptr::null(),
};
unsafe {
print_in_c(arg_ptr);
};
}
隨着這款C代碼:
#include <stdio.h>
int
print_in_c(const char *bar)
{
puts("C:");
puts(bar);
return 0;
}
但這並沒有工作。 代碼打印出當通過「foo」的的參數如下:接着是空白行
Some("foo")
C:
。
我得到了程序打印正確的文本,如果我鏽代碼更改爲以下:
extern crate libc;
use std::ffi::CString;
extern "C" {
fn print_in_c(opt_class: *const libc::c_char) -> libc::c_int;
}
fn main() {
let mut args = std::env::args();
//skip execuatble name
args.next();
let possible_arg = args.next();
println!("{:?}", possible_arg);
let mut might_be_necessary = CString::new("").unwrap();
let arg_ptr = match possible_arg {
Some(arg) => {
might_be_necessary = CString::new(arg).unwrap();
might_be_necessary.as_ptr()
}
None => std::ptr::null(),
};
unsafe {
print_in_c(arg_ptr);
};
}
運行時,該打印
Some("foo")
C:
foo
預期。
這種方法在技術上的工作,但它是尷尬延伸到多個參數,並導致編譯器警告:
warning: value assigned to `might_be_necessary` is never read
--> src/main.rs:19:9
|
19 | let mut might_be_necessary = CString::new("").unwrap();
| ^^^^^^^^^^^^^^^^^^^^^^
|
= note: #[warn(unused_assignments)] on by default
有沒有更好的方式來做到這一點?