我想在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
有没有更好的方式来做到这一点?