zplCore.comzplCore.com

29NativeAOT & Limits für fremde Eingaben

ZplCore, ZplCore.VectorLift, ZplCore.Testing, CLI und MCP-Server sind NativeAOT-kompatibel (IsAotCompatible, 0 Trim-/AOT-Warnungen). Rendering, Barcodes, Label-Modell, JSON, Compliance, Scan-Proof, Extraktion/Schwärzung, GS1, RFID, Printer Twin und Vector-Lift liefern unter NativeAOT dieselben Ausgaben wie mit JIT – build/aot-smoke.sh vergleicht rund 790 Ausgaben Byte für Byte (geprüft auf osx-arm64, linux-arm64 und linux-x64).

dotnet publish tools/ZplCli -p:PublishProfile=aot          # Host-RID, oder -r linux-arm64 / linux-x64 …
dotnet publish tools/ZplCore.Mcp -p:PublishProfile=aot
dotnet publish MyApp -c Release -p:PublishAot=true         # eigene App mit ZplCore-Referenz

Für NativeAOT-Container ohne .NET-Laufzeit empfiehlt sich mcr.microsoft.com/dotnet/runtime-deps:10.0-noble-chiseled-extra (distroless, non-root, inkl. ICU für kulturabhängige Formatierung; Gesamtgröße ~79–105 MB inkl. App). Im Praxistest auf einem Synology DS923+ NAS (linux-x64, AMD Ryzen Embedded R1600, 2 Kerne / 4 Threads, Synology Container Manager) lief der komplette Korpus unter NativeAOT 24 % schneller als unter JIT (10,7 s statt 14,0 s bei 793/793 identischen Ausgaben) und erreichte im NativeAOT-Container 237.428 Labels/s beim Parsen, 1.233 Labels/s beim Bitmap-Rendern und 295 PNG-Etiketten/s (> 17.500 PNGs/min). Auf 32-Bit-ARM-Geräten wie dem Raspberry Pi 2 (linux-arm / armv7l) läuft zplCore als Self-Contained- oder Framework-Dependent-Container auf aspnet:10.0-noble-chiseled-extra (174 MB), ab 64-Bit-ARM (linux-arm64, Raspberry Pi 4/5) direkt als NativeAOT.

Einschränkung bei POCO-Bindung: Mitglieder der obersten Ebene von T bleiben erhalten; verschachtelte Typen ([Supplier.Name]) entfernt der Trimmer, wenn sie nicht statisch referenziert sind. Unter NativeAOT wirft das eine MissingMemberException mit Typ, Mitglied und Abhilfe (TrimmerRootAssembly) statt eines leeren Felds. JSON-, Dictionary- und DataRow-Bindung sind nicht betroffen. NativeAOT braucht die native Toolchain der Plattform; musl/Alpine ist noch kein Ziel.

ZplLimits: ein Bereich für alles

Für fremde Eingaben (Uploads, Webdienste, Agents) setzt ZplLimits.Enforce harte Grenzen für jeden Renderer im Bereich – auch für die, die Compliance-Check, Scan-Proof, Import, Extraktion, GS1-Migration, Printer Twin, Cut-Plan und Vector-Lift intern anlegen, über Tasks und Parallel hinweg. Einstellungen werden auf den strengeren Wert gekappt, Schriftquellen, Systemschriften und Hintergrundbilder abgeschaltet; optional eine feste Uhr. Der MCP-Server führt jeden Aufruf in diesem Bereich aus.

// using ZplCore.Compliance;

using (ZplLimits.Enforce(new ZplLimits { MaxLabels = 10, MaxGraphicBytes = 4 << 20, FixedClock = DateTime.UnixEpoch }))
{
    // gilt für jeden Renderer in diesem Bereich – auch die, die Compliance, Scan-Proof,
    // Import, Extraktion, Printer Twin und Vector-Lift intern anlegen (auch über Tasks/Parallel)
    var report = ZplCompliance.Check(untrusted, CompliancePacks.Gs1LogisticLabel);
}