C语言接口有一个变长参数函数
extern "C" {
pub fn mkintn(n: c_long, ...) -> *mut c_long;
}
其中n
是变长部分的参数数目,它们都具有c_ulong
类型,请问语言层面有没有什么方法可以把它包装成如下的Rust函数
pub fn mkintn(args: &[c_ulong]) -> *mut c_long;
目前只能想到用内联汇编来workaround(还不清楚这样写有没有UB...)
pub fn mkintn(args: &[c_ulong]) -> *mut c_long {
let ret: *mut c_long;
unsafe { asm!(
"mov r12, rsp",
"mov r9 , 5 ",
"cmp r8 , r9 ",
"jbe 2f ",
"mov rcx, r9 ",
"sub rcx, r8 ",
"lea rsi, [r11 + r9 * 8]",
"lea rdi, [rsp + rcx * 8]",
"mov rsp, rdi",
"neg rcx ",
"rep movsq ",
"jmp 3f ",
"2:",
"mov r9 , r8 ",
"3:",
"mov rdi, r8 ",
"xor rax, rax",
"cmp rax, r9",
"jae 4f ",
"mov rsi, [r11 + rax * 8]",
"inc rax ",
"cmp rax, r9 ",
"jae 4f ",
"mov rdx, [r11 + rax * 8]",
"inc rax ",
"cmp rax, r9 ",
"jae 4f ",
"mov rcx, [r11 + rax * 8]",
"inc rax ",
"cmp rax, r9 ",
"jae 4f ",
"mov r8 , [r11 + rax * 8]",
"inc rax ",
"cmp rax, r9 ",
"jae 4f ",
"mov r9 , [r11 + rax * 8]",
"4:",
"xor rax, rax",
"call r10 ",
"mov rsp, r12",
inout("r11") args.as_ptr() => _,
inout("r8") args.len() => _,
out("rdi") _, out("rsi") _,
out("rdx") _, out("rcx") _,
out("r9") _, out("r12") _,
in("r10") ffi::mkintn, out("rax") ret,
); }
ret
}
1
共 3 条评论, 1 页
评论区
写评论rust这边可以用宏来实现变长参数。
上一个评论说的va_list 也只是在nightly版本中支持,稳定版本并不支持。
但是,我一直好奇的是,为啥rust不支持可变参数函数。
这个
va_list
好像是从C调用Rust实现的变长参数函数用的,来读取C提供的参数,我这里是从Rust调用C实现的变长参数函数,把所有参数写到一个切片中。--
👇
gwy15: https://www.google.com/search?q=rust+va_list
https://www.google.com/search?q=rust+va_list