C++ Quickstart
C++ components are the right choice when latency or throughput matters. They link against pipeml, the C++ runtime that ships with Pipelogic — geometry, image, tensor, detection mixins, Triton inference client.
Prerequisites
- Linux (Ubuntu 22.04 or 24.04). Use WSL on Windows.
- The
pplCLI on your PATH. See CLI install. - A Pipelogic account at app.pipelogic.ai/register.
You don't need Docker, you don't need to install the SDK. ppl release ships your sources to the platform; the platform builds the container image remotely with the 2-ml build system and links pipeml in.
1. Scaffold the component
mkdir threshold-image && cd threshold-image
mkdir src
touch component.yml src/main.cpp
ppl init will set up the workspace metadata for you in step 5.
2. Write component.yml
name: "Threshold image"
language: cpp
platform: linux/amd64
build_system: 2-ml
tags: ["latest", "default"]
worker:
input_type: Image
output_type: Image
config_schema:
threshold:
type: UInt64
default: 128
description: "Pixel intensity threshold (0–255)."
build_system: 2-ml is the standard C++ ML runtime. It gives you OpenCV 4, FFmpeg, GStreamer, gRPC, the Triton client, and pipeml — no extra setup.
3. Write the worker
src/main.cpp:
#include <opencv2/imgproc.hpp>
#include "pipelogic/cv/image.hpp"
#include "pipelogic/pipelogic.hpp"
using namespace ppl;
struct Params {
uint64_t threshold;
Params() {
auto cfg = parse_config();
threshold = read_config(cfg, "threshold").as<UInt64>();
}
};
PIPELOGIC_MAIN() {
Params params;
run([¶ms](ocv::Image img) -> ocv::Image {
img.convert(ocv::ColorSpace::GRAY);
cv::Mat& m = img.mutable_mat();
cv::threshold(m, m, params.threshold, 255, cv::THRESH_BINARY);
return img;
});
}
What's happening:
ocv::Imageis pipeml's high-level image wrapper. It carries the color-space tag and gives you direct access to the backingcv::Mat.img.convert(ColorSpace::GRAY)is in-place and a no-op when the image is already GRAY — no need to branch oncolor_space().img.mutable_mat()returns a mutable reference to the underlyingcv::Mat, socv::threshold(m, m, …)writes back into the same buffer — no per-tick allocation, no extra Image construction.parse_config()andread_config(...)pullconfig_schemavalues out ofcomponent.yml.PIPELOGIC_MAIN()is the entry-point macro. It expands into the appropriateint main(...)plus runtime init.run(worker)blocks until the backend closes.
You never construct pipelang values by hand — the typed wrapper classes (ocv::Image, ocv::BoundingBox, ocv::AudioFrame, etc.) do it for you.
4. Optional: extra build flags
For most components nothing else is needed. If your component has additional system dependencies, list them in component.yml:
xmake_packages:
- eigen
- sentencepiece
If you need apt packages baked into the runtime image, add a Dockerfile-base:
RUN apt-get update && apt-get install -y \
libtesseract-dev \
&& rm -rf /var/lib/apt/lists/*
If you need apt packages only at build time, use Dockerfile-build. Avoid build_system: custom unless you really need to override the entire build — both Dockerfile-base and Dockerfile-build work alongside build_system: 2-ml.
5. Initialize and release
ppl login
ppl init
ppl release
ppl release ships your sources; the platform compiles main.cpp with C++23, links pipeml, packages the resulting binary into a runtime image, and registers the new version in your workspace. Build time is typically 1–3 minutes.
6. Use it in a backend
In app.pipelogic.ai, wire up:
Input image file→ your Threshold image →Output browser video.
Click Run. The web UI shows a live preview and lets you adjust the threshold parameter on the fly via config.sync.