Cam*_*art 5 ffi variadic-functions rust
mexPrintf就像printf,接受一个varargs参数列表,但我不知道在Rust中包装它的最佳方法是什么.有一个可变参数泛型的RFC,但我们今天能做些什么呢?
在这个例子中,我想打印输入和输出的数量,但包装函数只打印垃圾.知道如何解决这个问题吗?
#![allow(non_snake_case)]
#![allow(unused_variables)]
extern crate mex_sys;
use mex_sys::mxArray;
use std::ffi::CString;
use std::os::raw::c_int;
use std::os::raw::c_void;
type VarArgs = *mut c_void;
// attempt to wrap mex_sys::mexPrintf
fn mexPrintf(fmt: &str, args: VarArgs) {
let cs = CString::new(fmt).unwrap();
unsafe {
mex_sys::mexPrintf(cs.as_ptr(), args);
}
}
#[no_mangle]
pub extern "system" fn mexFunction(
nlhs: c_int,
plhs: *mut *mut mxArray,
nrhs: c_int,
prhs: *mut *mut mxArray,
) {
let hw = CString::new("hello world\n").unwrap();
unsafe {
mex_sys::mexPrintf(hw.as_ptr());
}
let inout = CString::new("%d inputs and %d outputs\n").unwrap();
unsafe {
mex_sys::mexPrintf(inout.as_ptr(), nrhs, nlhs);
}
mexPrintf("hello world wrapped\n", std::ptr::null_mut());
let n = Box::new(nrhs);
let p = Box::into_raw(n);
mexPrintf("inputs %d\n", p as VarArgs);
let mut v = vec![3];
mexPrintf("vec %d\n", v.as_mut_ptr() as VarArgs);
}
Run Code Online (Sandbox Code Playgroud)
与流行的看法相反,可以调用 C中定义的variadic/vararg函数.这并不意味着这样做很容易,而且做坏事肯定更容易,因为编译器的类型更少检查你的工作.
这是一个打电话的例子printf.我对所有事情进行了硬编码:
extern crate libc;
fn my_thing() {
unsafe {
libc::printf(b"Hello, %s (%d)\0".as_ptr() as *const i8, b"world\0".as_ptr(), 42i32);
}
}
fn main() {
my_thing()
}
Run Code Online (Sandbox Code Playgroud)
请注意,我必须非常明确地确保我的格式字符串和参数都是正确的类型,并且字符串是NUL终止的.
通常,您将使用以下工具CString:
extern crate libc;
use std::ffi::CString;
fn my_thing(name: &str, number: i32) {
let fmt = CString::new("Hello, %s (%d)").expect("Invalid format string");
let name = CString::new(name).expect("Invalid name");
unsafe {
libc::printf(fmt.as_ptr(), name.as_ptr(), number);
}
}
fn main() {
my_thing("world", 42)
}
Run Code Online (Sandbox Code Playgroud)
Rust编译器测试套件还有一个调用可变参数函数的例子.
专门为一个字的警告printf式的功能:C编译器编写者意识到,人们搞砸了这种特殊类型的可变参数函数调用的所有的时间.为了帮助解决这个问题,他们编写了特殊的逻辑来解析格式字符串,并尝试根据格式字符串期望的类型检查参数类型.Rust编译器不会为您检查您的C风格格式字符串!
| 归档时间: |
|
| 查看次数: |
1589 次 |
| 最近记录: |