13.5.2.2 번거로운 FFI(Foreign Function Interface) 브릿지 배제 및 언어 간 인터페이스(Trait-Class) 추상화
자율주행의 엣지 런타임 시스템은 단일 언어의 순전함(Purity)을 허락하지 않는 난장판이다.
차량 제어는 안정성의 절대자 Rust가 쥐고 있고, 카메라 드라이버는 역전의 노장 C++가 움켜쥐고 있으며, 딥러닝 추론은 기민한 Python 인터프리터가 독식하고 있다. 기존의 로보틱스 프로그래머들은 이 세 언어의 메모리 공간을 억지로 연결하겠다고 악명 높은 수동 FFI(Foreign Function Interface) 바인딩을 짜며 C-ABI(C-Application Binary Interface) 헤더 규격을 수백 줄씩 수동으로 매핑(Mapping)하는 피눈물 나는 노가다를 감내해 왔다.
하지만, Zenoh-Flow 의 프레임워크 런타임은 이 지옥불에 기름을 붙이지 않는다. 본 절에서는, 시스템 엔지니어가 혐오스러운 수동 C-FFI 코딩을 한 줄도 짜지 않고, 오직 각 언어 본연의 우아한 클래스(Class)와 트레이트(Trait) 인터페이스만을 섭취하면서도 이기종 언어 간의 벽을 허무는 프레임워크 런타임 추상화의 사상을 터득한다.
1. 수동 FFI 바인딩의 찌꺼기 버그와 Unsafe 코드의 횡포
C++에서 짜 놓은 영상 필터 함수를 파이썬 스크립트에서 부르려면 어떤 짓을 해야 하는가?
보통 PyBind11 이나 ctypes 모듈을 가져와, C++의 함수 시그니처 형식을 파이썬의 구문으로 강제 변환하는 연결 브릿지 클래스를 수십 줄에 걸쳐 덕지덕지 발라야 한다. Rust에서 C++ 함수를 부를 때는 더 끔찍하다.
변수 메모리를 unsafe { } 블록으로 강제 격리시킨 후, 포인터 메모리 참조를 주고받으며 해제(Free) 타이밍의 불일치로 발생할지도 모르는 이중 해제(Double Free) 공포에 떨면서 C-스트링(Null-termination) 처리를 일일이 해야 한다.
이러한 수동 FFI 브릿지는 파이프라인의 오퍼레이터가 하나 추가될 때마다 개발자를 노가다성 코딩으로 옥죄고, 조금이라도 구조체가 바뀌면 컴파일러가 잡아주지 못해 런타임에 커널 코어 덤프(Core Dump)가 터지는 최강의 지뢰가 된다.
2. Zenoh-Flow 런타임의 언어 장벽 도살(Abstraction)
Zenoh-Flow 는 이 징그러운 개별 노드 간 FFI 매핑 작업을 아키텍트의 화면에서 완전히 소거시킨다.
파이프라인 매니페스트(YAML)를 구성할 때, 1번 노드가 C++ 공유 라이브러리(.so)이고 2번 노드가 파이썬 스크립트(.py)이며 3번 노드가 WebAssembly 바이너리(.wasm)라 할지라도, 아키텍트는 그저 각자를 “컴퓨터 세계의 공평한 이방인“으로 취급하고 하나의 야믈망(YAML)에 던져 넣으면 끝이다.
개발자는 오직 각자의 모국어로만 말한다(Native Interface).
- C++ 개발자: 자기가 잘 아는 C++
Operator기본 가상 클래스(Virtual Class)만 상속받아서 C++ 코드만 짠다. - Python 개발자: 평소 하던 대로 파이썬
Operator클래스를 만들고 객체를 리턴한다.
그렇다면 데이터는 어떻게 저 장벽을 넘어 타 언어로 꽂히는가?
Zenoh-Flow 의 백그라운드 코어 실행기(Daemon) 자체가 거대한 단일 FFI 통역사이자 브로커 역할을 수행한다. 데몬 내부의 C/Rust 코어가 C++ 노드로부터 던져진 데이터를 공통된 바이트 배열(zflow::Data 프로토콜 캡슐) 껍데기로 순식간에 포장한 뒤, 이를 내부 메모리 파이프라인을 쭉 태워 파이썬 런타임 엔진으로 쑤셔 넣는다. 그리고 파이썬 종속 C-Binding 코어가 이를 받아 memoryview 나 bytes 객체로 자동 치환시킨 후 파이썬 인터프리터의 아가리에 밀어 넣어주는 모든 복잡한 위임을 완전 자동(Auto-Generated Transparency) 으로 처리한다.
3. 언어 간 인터페이스(Trait/Class)의 순결성(Purity) 확보
결론적으로, 로보틱스 엔지니어는 언어를 섞어 쓰면서도 타 언어의 문법 구조(C-ABI)나 포인터 구조체의 형태에 신경 쓸 필요가 1퍼센트도 없어진다.
이 무거운 FFI 짐을 데몬 프레임워크 단으로 철저하게 위임(Offloading)해 버릴 때 얻는 최고의 권능은 ’조직의 완벽한 분업’이다.
C++를 짜는 로우레벨 시스템 엔지니어는 Rust를 알 필요가 없고, 파이썬을 만지는 딥러닝 연구원은 C++ 포인터에 벌벌 떨 필요가 없다. 각자는 프레임워크가 제공하는 자국어(Native) SDK 클래스만 하나 상속(Inherit)받아 데이터 가공 로직만 심으면, 데몬이 이것들을 실시간으로 후킹(Hooking)하여 우주적 잡탕 바벨탑(파이프라인)을 1밀리초의 오차도 없이 직조(Weaving)해 내는 기적을 발휘한다.
언어 간의 경계를 찢는 브릿지 공사를 수동(Manual FFI)으로 하는 자는 노가다의 수렁에 빠진 하수다.
모든 이질적인 통신과 메모리 이관을 표준화된 런타임 엔진(Zenoh 데몬)의 거대한 추상화 위장막(Abstraction Layer) 아래로 은폐 격리시켜 버리는 것. 그것이 멀티-언어(Polyglot) 초저지연 백엔드 아키텍처의 찬란한 결론이다.