* Разбор: `auto name = msg.get<std::string>(); auto a = msg.get<int>(); auto b = msg.get<int>();`
* Внутри хранится строка с простыми типовыми тегами (`i` для `int`, `s` для `std::string`), что позволяет в будущем перейти на бинарный формат без изменения API.
* `IpcPipeChannel` — реализация поверх двух FIFO (`/tmp/fifo_to_server`, `/tmp/fifo_to_client`), которая внутри работает со строками, но наружу — только с`IpcMessage`.
* **Уровень RPC-ядра**:
* `ProxyMarshaller` — собирает `IpcMessage` из имени метода и аргументов, отправляет через `RpcChannel` и читает ответ.
* `IpcMarshaller` — собирает `IpcMessage` из имени метода и аргументов, отправляет через `IpcChannel` и читает ответ.
* `RpcInvoker` — по имени метода (первое поле сообщения) находит зарегистрированную функцию-член и вызывает её, читая аргументы через `get<T>()`.
* **Сгенерированные обёртки**:
* `*.proxy.*` — используют `ProxyMarshaller` и `RpcChannel`, не зависят от конкретного транспорта.
* `*.skeleton.*` — используют `RpcInvoker` и принимают/возвращают `IpcMessage` для диспетчеризации вызовов.
* `*.proxy.*` — шаблонные классы, зависящие только от абстрактного `impl`с методом `impl.callTyped<Ret>(method, args...)` и не знающие про конкретный транспорт.
* `*.skeleton.*` — используют `RpcInvoker` и принимают/возвращают `RpcValue` для диспетчеризации вызовов.