ANSI C auf evrtng functions
Führen Sie nativen C-Code als Serverless-Funktion mit einer benutzerdefinierten Docker-Runtime auf evrtng functions aus. Maximale Performance, null Server zu verwalten.
Warum ANSI C?
Die Binary-Runtime führt Ihr kompiliertes C-Programm direkt aus — sein stdout wird zum HTTP-Response-Body. Das Binary in ein kleines Image packen, fertig ist die serverless C-Funktion. Das bringt Ihnen:
// Voraussetzungen
GCC
GCC-Compiler für lokale Tests (optional)
# API reachable (401 = yes, alive and requiring your key) $ curl -s -o /dev/null -w "%{http_code}" https://fnc4.evrtng.cloud/ping 401 $ docker --version Docker version 25.0.0 $ gcc --version gcc (Ubuntu 15.2.0-16ubuntu1) 15.2.0
Schritt-für-Schritt-Anleitung
Schreiben Sie Ihre C-Funktion
Die Binary-Runtime führt Ihr kompiliertes Programm direkt aus. JSON-Ergebnis nach stdout schreiben — das ist der HTTP-Response-Body. Alles auf stderr landet in den Plattform-Logs.
/* * evrtng functions – ANSI C function example * Prints a JSON result to stdout (the HTTP response body). */ #include <stdio.h> #include <stdlib.h> #include <string.h> int main(void) { /* Log to stderr – shows up in the platform logs */ fprintf(stderr, "[evrtng] ANSI C action invoked\n"); /* The response body */ printf("{ \"msg\": \"Hello from ANSI C!\" }\n"); return 0; }
# Compile $ gcc -o example example.c # Run it — same output your function returns $ ./example { "msg": "Hello from ANSI C!" }
Dockerfile erstellen
Kompiliertes Binary in ein minimales Image packen. Die Plattform mountet Ihr Image und führt das Binary aus — kein Runtime-Protokoll nötig.
# Stage 1 – Build FROM ubuntu:26.04 AS builder RUN apt-get update && \ apt-get install -y gcc libc-dev && \ rm -rf /var/lib/apt/lists/* WORKDIR /build COPY example.c . # Compile with optimisations and static linking RUN gcc -O2 -static -o example example.c # Stage 2 – Runtime (minimal scratch image) FROM ubuntu:26.04 RUN apt-get update && \ apt-get install -y libc6 && \ rm -rf /var/lib/apt/lists/* COPY --from=builder /build/example /usr/local/bin/example # The binary runs directly — stdout is the response ENTRYPOINT ["/usr/local/bin/example"]
Der Multi-Stage-Build hält das finale Image klein. Die Verwendung von -static für das C-Binary macht es vollständig selbstenthalten, sogar auf einem minimalen Base-Image.
Docker-Image builden & pushen
Image lokal bauen und in eine öffentlich pullbare Registry pushen. Ersetzen Sie YOUR_DOCKERHUB_USER durch Ihren Docker-Hub-Benutzernamen.
# Build the image $ docker build -t YOUR_DOCKERHUB_USER/ansi-c-hello . Step 1/8 : FROM ubuntu:26.04 AS builder ... Successfully built a1b2c3d4e5f6 Successfully tagged yourusername/ansi-c-hello:latest # Log in to Docker Hub $ docker login # Push the image $ docker push YOUR_DOCKERHUB_USER/ansi-c-hello The push refers to repository [docker.io/yourusername/ansi-c-hello] latest: digest: sha256:abc123... size: 27.4 MB # Verify the image is accessible $ docker pull YOUR_DOCKERHUB_USER/ansi-c-hello
Funktion über die API registrieren
Binär-Environment erstellen (einmalig), dann die Funktion aus Ihrem OCI-Image, dann einen HTTP-Trigger. Kein Gateway-Setup — jede Funktion bekommt ihre eigene Tenant-URL.
# 1. Create a binary environment (once per namespace) $ curl -X POST $API/v1/namespaces/$NS/environments \ -H "X-API-Key: $KEY" -H "Content-Type: application/json" \ -d '{"name": "cenv", "image": "ghcr.io/fission/binary-env:1.33.0"}' # 2. Create the function from your OCI image $ curl -X POST $API/v1/namespaces/$NS/functions \ -H "X-API-Key: $KEY" -H "Content-Type: application/json" \ -d '{"name": "ansi-c", "environment": "cenv", "oci_image": "YOUR_DOCKERHUB_USER/ansi-c-hello:latest", "entrypoint": "example"}' 201 Created # 3. Add an HTTP trigger $ curl -X POST $API/v1/namespaces/$NS/triggers \ -H "X-API-Key: $KEY" -H "Content-Type: application/json" \ -d '{"name": "ansi-c-http", "function": "ansi-c", "type": "http", "url": "/c", "method": "GET"}'
Aufrufen & Überwachen
Aufruf über Ihre Tenant-URL. Der erste Aufruf kann bis zu 60 s dauern (Firecracker-Kaltstart); warme Aufrufe antworten in Bruchteilen einer Sekunde.
# Invoke via your tenant URL $ curl "https://$NS.fnc4.evrtng.cloud/c" \ -H "X-API-Key: $KEY" { "msg": "Hello from ANSI C!" }
# Invocation history via the API $ curl $API/v1/namespaces/$NS/activations?limit=5 \ -H "X-API-Key: $KEY" # Your management actions (audit trail) $ curl $API/v1/namespaces/$NS/events \ -H "X-API-Key: $KEY"
JSON mit cJSON parsen
In der Praxis wollen Sie eingehendes JSON parsen. Hier ein vollständigeres Beispiel mit der leichten cJSON-Bibliothek.
action_json.c
#include <stdio.h> #include <stdlib.h> #include <string.h> #include "cJSON.h" /* cJSON: MIT License */ int main(void) { /* Read the request body from stdin */ char buf[4096] = {0}; fread(buf, 1, sizeof(buf) - 1, stdin); /* Parse input JSON */ cJSON *input = cJSON_Parse(buf); if (!input) { printf("{\"error\":\"invalid JSON\"}\n"); return 1; } /* Extract "name" field */ cJSON *name_item = cJSON_GetObjectItem(input, "name"); const char *name = (name_item && cJSON_IsString(name_item)) ? name_item->valuestring : "World"; /* Build and output the response */ cJSON *output = cJSON_CreateObject(); cJSON_AddStringToObject(output, "message", strcat(strcpy(malloc(64), "Hello, "), name)); cJSON_AddStringToObject(output, "runtime", "ANSI C"); printf("%s\n", cJSON_Print(output)); cJSON_Delete(input); cJSON_Delete(output); return 0; }
Dockerfile mit cJSON
FROM ubuntu:26.04 AS builder RUN apt-get update && apt-get install -y \ gcc libc-dev wget && \ rm -rf /var/lib/apt/lists/* # Download cJSON (MIT license) RUN wget -q \ https://raw.githubusercontent.com/DaveGamble/cJSON/master/cJSON.c \ https://raw.githubusercontent.com/DaveGamble/cJSON/master/cJSON.h WORKDIR /build COPY action_json.c cJSON.c cJSON.h . # Compile with cJSON RUN gcc -O2 -o action action_json.c cJSON.c -lm FROM ubuntu:26.04 RUN apt-get update && apt-get install -y libc6 && \ rm -rf /var/lib/apt/lists/* COPY --from=builder /build/action /usr/local/bin/action ENTRYPOINT ["/usr/local/bin/action"]
$ docker build -t YOU/ansi-c-json . $ docker push YOU/ansi-c-json # Register (once): environment + function + trigger $ curl -X POST $API/v1/namespaces/$NS/environments \ -H "X-API-Key: $KEY" -H "Content-Type: application/json" \ -d '{"name": "cenv", "image": "ghcr.io/fission/binary-env:1.33.0"}' $ curl -X POST $API/v1/namespaces/$NS/functions \ -H "X-API-Key: $KEY" -H "Content-Type: application/json" \ -d '{"name": "cjson", "environment": "cenv", "oci_image": "YOU/ansi-c-json:latest"}' { "message": "Hello, evrtng", "runtime": "ANSI C" }
Verwaltung Ihrer C-Action
# Update the function (after rebuild + push) $ curl -X PUT $API/v1/namespaces/$NS/functions/ansi-c \ -H "X-API-Key: $KEY" \ -d '{"oci_image": "USER/ansi-c-hello:v2"}' # Set memory (validated against your plan) $ curl -X PUT .../functions/ansi-c \ -d '{"resources": {"memory": "256Mi"}}' # Function details (incl. entrypoint, image) $ curl $API/v1/namespaces/$NS/functions/ansi-c \ -H "X-API-Key: $KEY" # Invocation history $ curl .../activations?limit=5 -H "X-API-Key: $KEY" # Delete the function $ curl -X DELETE .../functions/ansi-c \ -H "X-API-Key: $KEY" 200 OK
Implementierungshinweise
01
Die Binary-Runtime führt Ihr kompiliertes Programm aus und gibt dessen stdout als HTTP-Response-Body zurück.
02
Der Output muss gültiges JSON auf stdout sein. Alles auf stderr erscheint in den Aktivierungs-Logs (für Debugging verwenden).
03
Das Docker-Image muss öffentlich zugänglich sein oder in einer Registry gehostet werden, die mit evrtng functions konfiguriert ist.
04
Kompilieren Sie aus Sicherheitsgründen mit -fstack-protector-strong und validieren Sie alle Eingaben vor der Verwendung.
05
Wenn Sie Shared Libraries (openssl, curl etc.) benötigen, linken Sie diese statisch oder installieren Sie sie im Docker-Image.
06
cJSON (MIT-Lizenz) ist eine sichere Wahl für die JSON-Verarbeitung in C. libjansson und yyjson sind ebenfalls gute Alternativen.
