Worked examples of consuming nim-libp2p from C through the FFI bindings generated by nim-ffi.
The bindings are a header-only C API over a C ABI. Every generated method is asynchronous: it takes a result callback and returns immediately, and the callback fires from the library's dispatch thread. Library-initiated events (incoming streams, pub/sub messages) arrive through libp2p_ctx_add_on_…_listener callbacks. The examples turn each async call back into a blocking step with the small helpers in common.h.
echo.c— two TCP nodes; the server mounts a custom/cbind/echo/1.0.0protocol and echoes the bytes it reads, the client dials it and verifies the round-trip. The incoming-stream handler only hands the stream id tomain, which serves it inline, since calling back into the library from the dispatch thread would deadlock.gossipsub.c— two TCP nodes join a shared topic and exchange one message, delivered to the subscriber through its pub/sub-message listener.kad.c— two TCP nodes form a Kademlia DHT (a server, and a client that lists the server as its bootstrap node), then round-trip a value (kad_put_value/kad_get_value) and a provider record (create_cid,kad_start_providing/kad_get_providers) over the wire.relay.c— three TCP nodes: a relay, a destination and a source. The destination reserves a slot on the relay (circuit_relay_reserve); the source reaches it over a/p2p-circuitaddress (dial_circuit_relay) and sends a message the destination reads off its relayed stream.peerstore.c— drives one node's peerstore directly from a second node's PeerInfo:peerstore_add_peer,peerstore_get_peers,peerstore_get_peer_info, thenpeerstore_delete_peer. No dialing required.metrics.c— a running node dumps the process-wide Prometheus registry as JSON viacollect_metrics.
From cbind/, produce the runtime library and the generated header first:
nimble setup
nimble buildffi # -> ../build/liblibp2p.so
nimble genbindings_c # -> c_bindings/libp2p.hThen build the examples:
cd examples
cmake -S . -B build
cmake --build buildIf the vendored TinyCBOR sources can't be located automatically, point CMake at them:
cmake -S . -B build -DTINYCBOR_VENDOR=$(nimble path ffi)/ffi/codegen/templates/cpp/vendor./build/echo
./build/gossipsub
./build/kad
./build/relay
./build/peerstore
./build/metricsEach program exits 0 on success and prints the values it exchanged over the wire.