为啥 Rust 函数和 FFI C++ 函数以相反的顺序执行?
Posted
技术标签:
【中文标题】为啥 Rust 函数和 FFI C++ 函数以相反的顺序执行?【英文标题】:Why do a Rust function and a FFI C++ function execute in reverse order?为什么 Rust 函数和 FFI C++ 函数以相反的顺序执行? 【发布时间】:2018-03-25 11:13:09 【问题描述】:我尝试将外部 C++ 函数与我的 Rust 应用程序链接。此函数有效,但执行顺序与从 Rust 代码中调用的顺序不同。
为什么会这样?这有记录吗?
这里是 Rust 应用程序的列表:
extern crate libc;
use libc::c_int;
#[link(name = "Project1", kind = "static")]
extern "C"
pub fn lib_fun(i: c_int) -> c_int;
fn main()
unsafe
lib_fun(2);
println!("from Rust: ", 2);
“Project1”库如下所示:
#include <stdio.h>
extern "C"
int lib_fun(int t)
printf("from C++: %d\n", t);
return t;
预期输出:
from C++: 2
from Rust: 2
真正的输出是相反的顺序:
from Rust: 2
from C++: 2
外部函数lib_func
是否在另一个线程中执行?为什么?
详情:
平台:Windows 7、x64、 Rust:1.26.0(每晚), C++:Microsoft Visual Studio Community 2017 Preview 15.7.0 Preview 2.0 终端:IntelliJ IDEA 的集成终端。【问题讨论】:
绝对不是 threading (Rust 不会在你背后创建线程),所以我怀疑你在 stdout 上运行缓冲;这很奇怪,因为我认为在格式字符串中使用\n
会导致printf
立即刷新。
尝试在 C++ 中手动刷新stdout
。
@Veedrac 谢谢。我在 C++ 函数的末尾添加了fflush(stdout);
,事情就按正确的顺序发生了。
我无法在 Arch Linux x64 上使用 rustc 1.24.1 和 GCC 7.3.1 重现此问题。您使用的是哪个 C++ 编译器和哪个版本的 Rust?
@Michail:我不认为 Rust 是这里的问题,我怀疑你的 C++ 实现是。您使用的是哪个 C++ 编译器?视觉工作室? (哪个版本?)还是别的什么?
【参考方案1】:
外部 C++ 代码使用自己的缓冲区写入标准输出,并且比 Rust 调用者更晚刷新到系统缓冲区。 printf("...\n")
没有像我预期的那样刷新标准输出缓冲区。
相反,我需要手动刷新它,例如通过调用 fflush(stdout);
Thanks for this answer to @Veedrac
【讨论】:
这并不是普遍适用的。在带有 Clang (Apple LLVM version 9.0.0 (clang-900.0.39.2)
) 的 macOS 10.13.3 上,输出的顺序正确。在 Windows 10 上使用 Visual Studio 2017 时,该顺序也是正确的。这取决于平台标准库的实现细节——它应该在printf
中有换行符时刷新。
printf 的文档根本没有提到刷新。 我在***.com/questions/49475166/… 找到的这篇文章据我了解可能与\n
刷新但不应该。可能取决于操作系统和/或 C++ 编译器。
刷新行为通常随isatty(fileno(stdout))
而变化。因此,相同的操作系统、相同的代码、相同的编译器、相同的二进制文件,可以根据调用二进制文件的方式而具有不同的缓冲行为。以上是关于为啥 Rust 函数和 FFI C++ 函数以相反的顺序执行?的主要内容,如果未能解决你的问题,请参考以下文章