Ivan FB 03c9cbea36
docs(examples): add native (same-process) C++ example
Complements the CBOR C++ bindings (../cpp_bindings) with the native path: a C++
program that links the library and calls the native `<name>` ABI directly,
passing {.ffi.} structs by value and reading typed struct returns
(EchoResponse) from the callback — no CBOR, no tinycbor. An RAII TimerNode
wrapper bridges the async FFI-thread callback to a synchronous API via
std::future. README spells out native (same-process) vs CBOR (IPC). Verified
end-to-end with `make run`.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-05-31 18:37:20 +02:00

1.7 KiB

C++ example — native (same-process)

A C++ program that links the timer library directly and calls its native (zero-serialization) C ABI, with an idiomatic RAII wrapper. Struct returns come back as typed C structs read in the callback.

mytimer::TimerNode node("my-app");
std::cout << node.version();            // "nim-timer v0.1.0"
auto r = node.echo("hello", /*delayMs=*/5);
std::cout << r.echoed << " / " << r.timerName;

Native vs CBOR C++

This repository ships two C++ examples, matching the two ABIs:

Example ABI Use it for
cpp_native/ (this one) native <name> Same-process / local. Passes flat C structs by value, zero serialization.
../cpp_bindings/ CBOR <name>_cbor (tinycbor) Inter-process communication, where the request must be serialized to cross the boundary anyway.

In one address space the CBOR round-trip is pure overhead, so prefer this native path locally; reach for the CBOR bindings only when you actually cross a process/machine boundary (see also ../ipc).

Build & run

cd examples/timer/cpp_native
make run

This compiles libmy_timer.{dylib,so} and runs ./example. Each call is dispatched on the library's background FFI thread; the wrapper blocks on a std::future until the result callback fires. A struct return (EchoResponse) is delivered as a const EchoResponse* in the callback — valid only for the callback's lifetime, so the wrapper copies its fields out before returning.

The native header comes from ../c_bindings/my_timer.h (the C and C++ native examples share it); regenerate it with nimble genbindings_c.