为什么在 Rust 中链接和调用带有可变参数的 C 函数会导致调用随机函数?
Why linking and calling a C function with variadic arguments in Rust causes random functions to be called?
我在玩 Rust FFI,我试图 link printf
C 函数,它有可变参数,我的 Rust 可执行文件。在我 运行 可执行文件之后,我目睹了一些 st运行ge 行为。
这是我的 Rust 代码:
use cty::{c_char, c_int};
extern "C" {
fn printf(format: *const c_char, ...) -> c_int;
}
fn main() {
unsafe {
printf("One number: %d\n".as_ptr() as *const i8, 69);
printf("Two numbers: %d %d\n".as_ptr() as *const i8, 11, 12);
printf(
"Three numbers: %d %d %d\n".as_ptr() as *const i8,
30,
31,
32,
);
}
}
这是运行 cargo run
:
之后的输出
cargo run
Compiling c-bindings v0.1.0 (/home/costin/Rust/c-bindings)
Finished dev [unoptimized + debuginfo] target(s) in 0.20s
Running `target/debug/c-bindings`
One number: 1
Two numbers: 1 11376
Three numbers: 0 0 0
Two numbers: 11 12
Three numbers: 0 0 56
Three numbers: 30 31 32
我看起来像第一个 printf
使用 运行dom 参数调用第二个和第三个,然后第二个 printf
使用 运行dom 参数调用第三个因为预期的输出应该是:
One number: 1
Two numbers: 11 12
Three numbers: 30 31 32
任何人都可以向我解释为什么会发生这种 st运行ge 行为吗?
Rust 字符串不像 printf
期望的那样 null-terminated。您需要在格式字符串末尾手动包含 [=13=]
或使用 CString
:
printf("One number: %d\n[=10=]".as_ptr() as *const i8, 69);
use std::ffi::CString;
let s = CString::new("One number: %d\n").unwrap();
printf(s.as_ptr(), 69);
我在玩 Rust FFI,我试图 link printf
C 函数,它有可变参数,我的 Rust 可执行文件。在我 运行 可执行文件之后,我目睹了一些 st运行ge 行为。
这是我的 Rust 代码:
use cty::{c_char, c_int};
extern "C" {
fn printf(format: *const c_char, ...) -> c_int;
}
fn main() {
unsafe {
printf("One number: %d\n".as_ptr() as *const i8, 69);
printf("Two numbers: %d %d\n".as_ptr() as *const i8, 11, 12);
printf(
"Three numbers: %d %d %d\n".as_ptr() as *const i8,
30,
31,
32,
);
}
}
这是运行 cargo run
:
cargo run
Compiling c-bindings v0.1.0 (/home/costin/Rust/c-bindings)
Finished dev [unoptimized + debuginfo] target(s) in 0.20s
Running `target/debug/c-bindings`
One number: 1
Two numbers: 1 11376
Three numbers: 0 0 0
Two numbers: 11 12
Three numbers: 0 0 56
Three numbers: 30 31 32
我看起来像第一个 printf
使用 运行dom 参数调用第二个和第三个,然后第二个 printf
使用 运行dom 参数调用第三个因为预期的输出应该是:
One number: 1
Two numbers: 11 12
Three numbers: 30 31 32
任何人都可以向我解释为什么会发生这种 st运行ge 行为吗?
Rust 字符串不像 printf
期望的那样 null-terminated。您需要在格式字符串末尾手动包含 [=13=]
或使用 CString
:
printf("One number: %d\n[=10=]".as_ptr() as *const i8, 69);
use std::ffi::CString;
let s = CString::new("One number: %d\n").unwrap();
printf(s.as_ptr(), 69);