RPC framework for embedded systems. Generates C++ server code and a Python client from a single YAML definition file. Built on ETL — no dynamic memory allocations, no exceptions, no RTTI.

How it works

graph TD
    DEF["example.lrpc.yaml\nYAML interface definition"]
    LRPCG("lrpcg cpp")

    subgraph GEN["Generated C++"]
        SRV_GEN["Server class\nframing · serialization · dispatch"]
        SHIM_GEN["Service shim\none pure-virtual function per RPC call"]
    end

    subgraph IMPL["Your implementation — two classes"]
        MY_SRV["MyServer\nlrpcTransmit → UART · SPI · TCP · …"]
        MY_SVC["MyService\nadd() · get_temperature() · …"]
    end

    TRANSPORT("Transport\nserial · Bluetooth · TCP · …")

    subgraph CLIENT["Client — PC · Python"]
        CLI["lrpcc\nCLI tool, no code needed"]
        LIB["LrpcClient\ncustom Python code"]
    end

    DEF -->|"lrpcg cpp -d"| LRPCG
    LRPCG --> GEN
    DEF -.->|also used by| CLIENT
    SRV_GEN -->|"inherit"| MY_SRV
    SHIM_GEN -->|"inherit + implement"| MY_SVC
    MY_SRV <-->|"lrpcReceive / lrpcTransmit"| TRANSPORT
    TRANSPORT <-->|"function calls + responses"| CLIENT

Define your interface once in YAML. LotusRPC generates everything else: the C++ server class, all serialization and framing code, and the service shim with one pure-virtual function per RPC call. You write two classes: wire lrpcTransmit to your hardware, and implement your business logic in the service shim. LotusRPC handles the rest.

Get started   Reference   C++ API   Python API   Examples

Key features

  • Suitable for embedded — no dynamic memory, no exceptions, no RTTI
  • Transport agnostic — serial, Bluetooth, TCP — any byte-oriented channel works
  • YAML definitions — definition files use the .lrpc.yaml extension by convention; schema-validated, editor-friendly, easy to parse or extend
  • Code generationlrpcg produces all C++ server code in one command
  • CLI clientlrpcc lets any team member call remote functions without writing code
  • Streams — client-to-server and server-to-client data streams, finite or infinite
  • C++11 compatible — works on any platform with a modern C++ compiler

Quick example

Define an interface in YAML:

name: example
settings:
  namespace: ex
services:
  - name: math
    functions:
      - name: add
        params:
          - { name: a, type: int32_t }
          - { name: b, type: int32_t }
        returns:
          - { name: result, type: int32_t }

Generate code, implement the function, and call it from the command line:

lrpcg cpp -d example.lrpc.yaml -o generated/
lrpcc math add 3 7   # prints: result = 10

See Getting started for a complete walkthrough.

Supported data types

Category Types
Integer uint8_t, int8_t, uint16_t, int16_t, uint32_t, int32_t, uint64_t, int64_t
Float float, double
Bool bool
String string (auto size), string_N (fixed size N)
Bytearray bytearray — flexible-length byte buffer
Array Any type with count: N (N ≥ 2)
Optional Any type with count: ?
Struct Composite user-defined type
Enum User-defined enumeration, translated to enum class

For details on each type and the C++ mappings, see the C++ API reference and the interface definition reference.