Rerun C SDK 实战:用 rr_spawn 启动 Rerun Viewer 进程并监听 gRPC 连接
【免费下载链接】rerunVisualize, query, and stream to train on multimodal robotics data.项目地址: https://gitcode.com/GitHub_Trending/re/rerun
导读
本文以仓库中的 C 语言示例 spawn_viewer 为主线,讲解如何在 C 程序中通过 Rerun C SDK 的rr_spawn函数启动一个独立的 Rerun Viewer 进程,使其就绪后监听 gRPC 端口,供随后的录制数据流连接。读完本文,你将掌握rr_spawn的调用方式、错误处理约定、底层实现链路,以及可自定义的 Viewer 启动选项(端口、内存上限、可执行文件路径等),并能据此在自己的 C 项目中无缝嵌入 Rerun 可视化能力。
示例概述:一行 C 代码拉起 Viewer
该示例的核心目标非常明确:启动一个全新的 Rerun Viewer 进程,该进程准备好监听 gRPC 连接,并借助 PATH 中可用的可执行文件完成启动。完整示例仅有 main.c 一个源文件,运行方式为:
make run在仓库中,这一主题在三种语言下均有对等示例,README 描述完全一致:
- C 版本:examples/c/spawn_viewer
- C++ 版本:examples/cpp/spawn_viewer
- Rust 版本:examples/rust/spawn_viewer
源码逐行解析:rr_spawn 的调用与错误处理
main.c 的完整实现如下:
#include <rerun.h> #include <stdio.h> int main(void) { rr_error error = {}; rr_spawn(NULL, &error); if (error.code != 0) { printf("Error occurred: %s\n", error.description); return 1; } }整个程序只有三步:
- 声明错误结构体:
rr_error error = {};以零初始化错误对象,这是 Rerun C API 的通用约定——所有可能失败的接口都会接收一个rr_error *输出参数; - 调用
rr_spawn(NULL, &error):NULL表示使用全部默认的 Viewer 启动选项(不传入自定义rr_spawn_options),Viewer 进程由 SDK 负责派生; - 检查错误码:若
error.code != 0,打印error.description并返回非零退出码;否则正常退出。
该示例刻意不做后续的数据发送,仅验证「spawn 一个 Viewer 进程」这一最小链路。若 spawn 失败(例如 PATH 中找不到rerun可执行文件),程序会在终端输出具体失败原因并以状态码 1 退出,方便在脚本中捕获失败。
底层实现:rr_spawn 在 Rust SDK 中的调用链
rr_spawn是 Rerun C SDK(Rust 编写的 FFI 层)导出的 C ABI 符号,其实现位于 crates/top/rerun_c/src/lib.rs:
fn rr_spawn_impl(spawn_opts: *const CSpawnOptions) -> Result<(), CError> { let spawn_opts = if spawn_opts.is_null() { re_sdk::SpawnOptions::default() } else { let spawn_opts = ptr::try_ptr_as_ref(spawn_opts, "spawn_opts")?; spawn_opts.as_rust()? }; // Port is unused here — this function only spawns the viewer process. // The C SDK connects separately via `rr_recording_stream_spawn`. re_sdk::spawn(&spawn_opts) .map(drop) .map_err(|err| CError::new(CErrorCode::RecordingStreamSpawnFailure, &err.to_string()))?; Ok(()) } #[unsafe(no_mangle)] pub extern "C" fn rr_spawn(spawn_opts: *const CSpawnOptions, error: *mut CError) { if let Err(err) = rr_spawn_impl(spawn_opts) { err.write_error(error); } }从源码可以提炼出几个关键实现事实:
- 空指针即默认选项:当 C 侧传入
NULL时,Rust 侧会退化为re_sdk::SpawnOptions::default(),这与示例中rr_spawn(NULL, &error)的用法一一对应; - 错误映射:spawn 过程一旦失败,会被统一包装为
CErrorCode::RecordingStreamSpawnFailure错误码,连同可读的错误信息字符串一起写入rr_error,这正是 main.c 中error.code != 0分支所能捕获的错误来源; - 职责划分明确:源码注释明确指出,
rr_spawn只负责派生 Viewer 进程本身,端口在这里并不使用;C SDK 后续的数据连接由独立的rr_recording_stream_spawn接口完成。也就是说,示例展示的是「先拉起 Viewer」这一步,随后录制流可以再以相同或更高的端口与这个 Viewer 建立 gRPC 连接。
启动选项详解:rr_spawn_options / SpawnOptions 全部字段
虽然示例使用了NULL(全默认值),但rr_spawn也接受自定义选项。C 头文件 rerun.h 中的rr_spawn_options与 C++ 侧的 SpawnOptions 保持同步(头文件注释明确要求两者一致),其字段及默认值如下:
| 字段 | 默认值 | 说明 |
|---|---|---|
port | 9876 | Viewer 的 gRPC 服务监听端口;Rust 实现注释表明在rr_spawn路径下该端口当前未实际使用 |
memory_limit | "75%" | Viewer 进程内存上限,达到上限后 Rerun 会丢弃最旧的数据;可写为16GB或50%(系统总内存百分比)等格式 |
server_memory_limit | "1GiB" | 与 Viewer 同进程运行的 gRPC 服务器的内存上限,超限同样丢弃最旧数据 |
hide_welcome_screen | false | 是否隐藏 Rerun 的正常欢迎界面 |
detach_process | true | 是否将 Viewer 进程从应用进程中分离(默认分离,应用退出不影响 Viewer) |
executable_name | "rerun" | 要启动的 Rerun 可执行文件名称;Windows 上可省略.exe后缀 |
executable_path | 空 | 显式指定某个可执行文件的完整路径,替代在 PATH 中按executable_name搜索 |
其中executable_name与executable_path直接对应了示例描述中的 "using an executable available in PATH"——默认行为就是在 PATH 中查找名为rerun的可执行文件;而executable_path则提供了一条绕过 PATH 搜索、强制指定路径的逃生通道,适合 Viewer 二进制被安装到非标准位置或在 CI 中固定版本时使用。memory_limit/server_memory_limit的字符串格式支持绝对值(如16GB)与百分比(如50%)两种写法,若格式非法,Rust 侧还存在专门的CErrorCode::InvalidMemoryLimit错误码。
跨语言对照:C / C++ / Rust 的 spawn 写法
同一主题在三种语言下各有一个最小示例,便于对照学习:
C(本示例):main.c
rr_error error = {}; rr_spawn(NULL, &error); if (error.code != 0) { printf("Error occurred: %s\n", error.description); return 1; }C++:main.cpp
#include <rerun.hpp> int main() { rerun::spawn().exit_on_failure(); }C++ 侧使用 RAII 风格的rerun::spawn(),并通过exit_on_failure()在失败时直接退出,是 C 语言手动检查rr_error的语义等价封装。
Rust:examples/rust/spawn_viewer,运行方式为:
cargo run --release -p spawn_viewer三种语言对应关系清晰:C API 的rr_spawn(NULL, &error)↔ C++ 的rerun::spawn()↔ Rust SDK 的re_sdk::spawn(&SpawnOptions::default()),底层最终都会汇聚到re_sdk::spawn这一 Rust 核心实现。
构建与运行
C 示例通过make run一键构建并运行,前提是:
- 已构建并安装 Rerun C SDK(提供
rerun.h头文件与rerun_c链接库); - 已安装 Rerun Viewer 可执行文件,且其名称位于 PATH 中(默认查找
rerun,也可通过executable_path显式指定)。
运行成功后,屏幕上会弹出一个新的 Rerun Viewer 窗口(默认detach_process = true,独立于示例进程运行),随后便可通过 gRPC 向该 Viewer 推送数据。若运行时未见窗口或程序以退出码 1 结束,可检查终端输出的error.description判断是 PATH 中缺少rerun、可执行文件版本不匹配,还是端口被占用等具体原因。
小结
spawn_viewer示例虽短,却完整演示了 Rerun C SDK 的进程派生能力:rr_spawn(NULL, &error)一行调用即可在 PATH 中定位 Viewer 可执行文件、以默认(或自定义)选项拉起独立 Viewer 进程并使其就绪监听 gRPC 连接。结合 crates/top/rerun_c/src/lib.rs 的 FFI 实现与 spawn_options.hpp 中的字段定义,开发者可以据此进一步定制端口、内存上限、欢迎页与进程分离行为,将 Rerun 可视化无缝嵌入任意 C 项目中。
【免费下载链接】rerunVisualize, query, and stream to train on multimodal robotics data.项目地址: https://gitcode.com/GitHub_Trending/re/rerun
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考