You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

147 lines
3.9 KiB
Markdown

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

# Minimal C++ RPC PoC with Auto-Code Generation
Простой Proof-of-Concept реализации RPC для C++ с автоматической генерацией прокси и скелета по аннотациям в исходниках.
Проект демонстрирует:
* Парсинг исходников C++ с помощью `libclang` для поиска аннотированных классов и методов.
* Автоматическую генерацию файлов:
* `*.proxy.h/cpp` — клиентский прокси для вызова удалённых методов.
* `*.skeleton.h/cpp` — серверный скелет для приёма запросов и вызова реальных методов.
* Минимальный протокол передачи данных через **именованные каналы (FIFO)**.
* Поддержка только типов `int` для аргументов и возвращаемого значения (PoC).
---
## Структура проекта
```
project/
├── CMakeLists.txt
├── README.md
├── src
│   ├── client.cpp
│   ├── MyService.cpp
│   ├── MyService.h
│   ├── rpc_export.h
│   └── server.cpp
├── tools
│ ├── generate_rpc.py
│ └── templates
│ ├── proxy.cpp.j2
│ ├── proxy.h.j2
│ ├── skeleton.cpp.j2
│ └── skeleton.h.j2
└─ build/ # создаётся при сборке
```
---
## Зависимости
* CMake ≥ 3.10
* GCC или Clang с поддержкой C++17
* Python 3.8+ с пакетами:
```bash
pip3 install jinja2 clang
```
* libclang (для Python)
Если GCC используется только для сборки — libclang нужен только для генератора.
**Важно**: Сам `libclang` и пакет `clang` для Python должны быть одной версии.
---
## Аннотации для экспорта
Управление тем, какие атрибуты каких классов следует экспортировать происходит с помощью
аннотаций в исходном коде.
См. файл [MyService.h](src/MyService.h):
```c
class RPC_EXPORT MyService {
public:
RPC_EXPORT
int add(int a, int b);
int minus(int a, int b);
};
```
* Экспортируем класс `MyService`:
* Экспортируем метод `MyService::add`;
* Но **не** экспортируем метод `MyService::minus`.
---
## Сборка проекта
1. Конфигурируем CMake:
```bash
cmake -DCMAKE_EXPORT_COMPILE_COMMANDS=ON -B build
```
Директива `CMAKE_EXPORT_COMPILE_COMMANDS=ON` нужна для корректного парсинга в `libclang`.
2. Собираем проект:
```bash
cmake --build build
```
В результате получаем два бинарника:
```
./build/server
./build/client
```
---
## Генерация кода
Автоматическая генерация прокси и скелета происходит **при сборке** через Python-скрипт `tools/generate_rpc.py`.
Пример ручного запуска генератора:
```bash
python3 tools/generate_rpc.py \
--out-dir build/generated \
--compile-commands build/compile_commands.json \
src/MyService.h
```
Сгенерированные файлы попадут в:
```
build/generated/
├─ MyService.proxy.h
├─ MyService.proxy.cpp
├─ MyService.skeleton.h
└─ MyService.skeleton.cpp
```
---
## Запуск
1. В одном терминале запускаем сервер:
```bash
./server
```
2. В другом терминале — клиент:
```bash
./client
```
**Ожидаемый вывод:**
```
RESULT: 15
```