mirror of
https://github.com/logos-messaging/nim-ffi.git
synced 2026-06-20 16:29:31 +00:00
The native C ABI only works in-process. This example demonstrates the other half — the CBOR ABI crossing a process (and machine) boundary — since the `ctx` pointer is process-local and cannot travel over the wire. A server links libmy_timer, owns one context, and serves method calls; a client links nothing (it only needs the FfiCbor encoder/ffi_decode_text in my_timer_cbor.h) and speaks the same CBOR over a socket. Both binaries accept `--unix <path>` for two processes on one host and `--tcp <host> <port>` for two machines — the only difference is the socket family, so one client/server pair covers both scenarios. Framing is length-prefixed in network byte order so the endpoints may differ in OS, arch, or endianness. `proto.h` carries the shared framing, the CBOR request builders, and a small CBOR map reader so the client can pull text fields out of a response without a full CBOR library. Verified end-to-end over both AF_UNIX and TCP loopback. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
55 lines
1.8 KiB
Makefile
55 lines
1.8 KiB
Makefile
# Build the IPC (CBOR-over-socket) timer example.
|
|
#
|
|
# make # build the Nim dylib, the server, and the client
|
|
# make demo # run a full same-machine round-trip over a unix socket
|
|
# make clean
|
|
#
|
|
# The server links libmy_timer; the client does not (it only needs the CBOR
|
|
# encoder/decoder in my_timer_cbor.h). The Nim library is compiled from the
|
|
# repository root so its vendored Nimble dependencies resolve.
|
|
|
|
# Generated my_timer.h / my_timer_cbor.h live in ../c_bindings.
|
|
REPO_ROOT := $(abspath ../../..)
|
|
NIM_SRC := $(REPO_ROOT)/examples/timer/timer.nim
|
|
HDR_DIR := ../c_bindings
|
|
|
|
UNAME_S := $(shell uname -s)
|
|
ifeq ($(UNAME_S),Darwin)
|
|
LIBNAME := libmy_timer.dylib
|
|
RPATH := -Wl,-rpath,.
|
|
else
|
|
LIBNAME := libmy_timer.so
|
|
RPATH := -Wl,-rpath,'$$ORIGIN'
|
|
endif
|
|
|
|
CC ?= cc
|
|
# proto.h is a shared static-inline header; each TU uses a subset of it, so
|
|
# unused-function warnings are expected and silenced.
|
|
CFLAGS ?= -std=c11 -Wall -Wextra -Wno-unused-function -O2 -I. -I$(HDR_DIR)
|
|
NIMFLAGS := --mm:orc -d:chronicles_log_level=WARN --app:lib --noMain \
|
|
--nimMainPrefix:libmy_timer
|
|
SOCK := /tmp/my_timer.sock
|
|
|
|
.PHONY: all demo clean
|
|
|
|
all: server client
|
|
|
|
$(LIBNAME):
|
|
cd $(REPO_ROOT) && nim c $(NIMFLAGS) -o:$(CURDIR)/$(LIBNAME) $(NIM_SRC)
|
|
|
|
server: server.c proto.h $(HDR_DIR)/my_timer_cbor.h $(LIBNAME)
|
|
$(CC) $(CFLAGS) server.c -L. -lmy_timer -lpthread $(RPATH) -o server
|
|
|
|
client: client.c proto.h $(HDR_DIR)/my_timer_cbor.h
|
|
$(CC) $(CFLAGS) client.c -o client
|
|
|
|
# Same-machine demo: start the server on a unix socket, run the client, stop.
|
|
demo: all
|
|
@./server --unix $(SOCK) & echo $$! > .srv.pid; \
|
|
sleep 1; \
|
|
./client --unix $(SOCK); \
|
|
kill `cat .srv.pid` 2>/dev/null; rm -f .srv.pid $(SOCK)
|
|
|
|
clean:
|
|
rm -f server client $(LIBNAME) .srv.pid $(SOCK)
|