Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

libc 与 C 运行时互操作

说明

  • 本页记录 Rust 与 C 运行时交互时的一个实际片段: 自定义 printf.
  • 适合处理“C 库输出和宿主程序日志时序不同步”的场景.

自定义 printf

遇到过这样一种情况: Rust 调用 C 函数时, 最终编译出的进程由 C# 宿主启动, printf 的输出相对 Rust 日志存在滞后, 因此用 Rust 导出的 r_printf 替代 C 侧的 printf.

C 侧替换方式:

int r_printf(const char *format, ...);

#define printf r_printf
#define DBGPRINTF r_printf

Rust 侧实现:

#![allow(unused)]
fn main() {
use std::io::Write;
use printf_compat::{format, output};

#[no_mangle]
pub unsafe extern "C" fn r_printf(ss: *const i8, mut args: ...) -> i32 {
    let mut s = String::new();
    let bytes_written = format(ss, args.as_va_list(), output::fmt_write(&mut s));
    print!("{}", s);
    std::io::stdout().flush().unwrap();
    bytes_written
}
}

使用场景

  • C 库和 Rust 日志需要统一输出顺序.
  • 宿主程序对 stdout 的刷新时机较敏感.
  • 需要在 Rust 侧接管 C 风格可变参数打印入口.

注意

  • 这种做法更偏工程层兼容技巧, 要注意 ABI 和可变参数实现方式.
  • 若跨平台使用, 需要进一步验证不同目标平台上的可用性.