mexPrintf
, как и printf
, принимает список аргументов varargs. Я не знаю, как лучше всего обернуть это в Rust. Существует RFC for variadic generics, но что мы можем сделать сегодня?Как обернуть вызов функции FFI, которая использует VarArgs в Rust?
В этом примере я хочу напечатать количество входов и выходов, но обернутая функция просто печатает мусор. Любая идея, как это исправить?
#![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);
}
Обновление: я спутал variable list of arguments
с va_list
. Я собираюсь избежать обоих, если смогу и в этой ситуации, я просто собираюсь выполнить форматирование строк в Rust, прежде чем передавать его для взаимодействия. Вот то, что работает для меня в этом случае:
#![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;
// attempt to wrap mex_sys::mexPrintf
fn mexPrintf(text: &str) {
let cs = CString::new(text).expect("Invalid text");
unsafe { mex_sys::mexPrintf(cs.as_ptr()); }
}
#[no_mangle]
pub extern "C" fn mexFunction(nlhs: c_int, plhs: *mut *mut mxArray, nrhs: c_int, prhs: *mut *mut mxArray){
mexPrintf(&format!("{} inputs and {} outputs\n", nrhs, nlhs));
}
Вы имеете в виду, что mexPrintf принимает переменное количество аргументов, таких как 'printf', или' va_list' как 'vprintf'? Если первое вам нужно передать целое число напрямую, а не как указатель на него. –
Спасибо @ChrisEmerson, я, к сожалению, получил два смущения. Спасибо, что помогли прояснить это. –