Net-Base Magazin

19.04.2026

Régi Delphi-projektek Unicode-migrációja: buktatók, stratégia és tiszta megvalósítás

Sok Delphi-t használó meglévő alkalmazás még mindig ANSI-karakterláncokkal dolgozik. A Unicode-migráció több, mint egy fordítókapcsoló: érinti az adatelérést, az interfészeket, a riportokat, a harmadik féltől származó könyvtárakat és a teszteket. Ez a cikk egy gyakorlati migrációs útvonalat mutat be – beleértve...

19.04.2026

A régi Delphi-projektek Unicode-migrációja sok vállalatnál szükséges lépés, mivel a meglévő alkalmazások egyébként a nemzetközi adatok, a modern operációs rendszerek, az integrációk és az új interfészek esetén egyre inkább korlátokba ütköznek. A gyakorlatban ez ritkán működik úgy, hogy „recompile és kész”. Delphi az Unicode-verzióktól kezdve (Delphi 2009-től) alapvető változtatásokat vezetett be a standard string-típusokban. Ennek következtében megváltoznak a feltételezések a karakterkódolásról, a memóriaelrendezésről és az API-szignatúrákról. Aki ezt alábecsüli, lassan felbukkanó adatproblémákat, hibás exportokat, tisztázatlan support-ügyeket és biztonsági kockázatokat okozhat.

Ez a cikk egy műszakilag terhelhető eljárást ad: hogyan elemezze a meglévőt, hogyan határozza meg ésszerűen a scope-ot, hogyan csökkentse a kockázatokat a kritikus pontokon (adatbázisok, fájlok, Windows-API-k, COM, REST-szolgáltatások) és hogyan biztosítsa a migrációt úgy, hogy az üzem és a továbbfejlesztés párhuzamosan folytatható maradjon. A fókusz Delphi-tipikus buktatókra irányul VCL-alkalmazásokban, szolgáltatásokban és interfészeknél – figyelemmel a modernizációs utakra, amelyek később olyan témákat is befogadhatnak, mint a BDE-kiváltás natív kapcsolattal, REST-szerver vagy multiplatform megoldások.

Warum die Unicode-Umstellung in Delphi so oft „größer als gedacht“ ist

In klassischen Delphi-Versionen war string ein ANSI-String (je nach Systemcodepage). Seit Delphi 2009 ist string standardmäßig ein UnicodeString (UTF-16). Gleichzeitig wurden viele Bibliotheken und VCL-Klassen auf Wide-APIs umgestellt. Das ist grundsätzlich positiv, weil es internationale Zeichen robust unterstützt. Aber: Legacy-Code ist häufig über Jahre um die Annahmen „1 Zeichen = 1 Byte“, „PChar ist PAnsiChar“ oder „Length() entspricht Byte-Anzahl“ gewachsen.

Miért lesz az Delphi Unicode-átállása gyakran nagyobb, mint gondolnánk

A klasszikus Delphi-verziókban a string ANSI-stringként viselkedett (rendszerfüggő kódlappal). Delphi 2009 óta a string alapértelmezés szerint UnicodeString (UTF-16). Egyidejűleg sok könyvtár és VCL-osztály Wide-API-kat használ. Ez alapvetően előnyös, mert robusztusan támogatja a nemzetközi karaktereket. Ugyanakkor a legacy-kód gyakran hosszú éveken át a „1 karakter = 1 byte”, „PChar == PAnsiChar” vagy „Length() == bájtszám” feltevésekre épült.

Azok a tipikus okok, amiért a migrációk bonyolultabbak lesznek:

  • Implicit konverziók történnek ugyan, de megváltoztathatják az adatokat (különösen fájloknál, interfészeknél vagy adatbázis BLOB-/Text-mezőknél).
  • Byte-orientált kód (stream-ek, buffer, hashing, titkosítás) észrevétlenül hibássá válik, ha string-tartalmakat bájtként kezelnek.
  • Harmadik fél komponensek részben csak ANSI-t támogatnak, vagy saját string-típusokat és callbackeket használnak.
  • Külső környezet (Windows-API-k, COM, nyomtatás/reporting, EDI, CSV, XML/JSON) meghatározott kódolásokat vár el.

A cél ezért nem az, hogy „lehetőleg minél kevesebbet változtassunk”, hanem hogy célzottan ott módosítsunk, ahol az adatáramlás és a kódolás meghatározható kell legyen. Egy tiszta Unicode-migráció egyúttal lehetőség arra is, hogy a korábban homályos kódolási határokat végre dokumentáljuk és teszteljük.

Technische Grundlagen: Delphi-Stringtypen, Encodings und ihre Nebenwirkungen

string, UnicodeString, AnsiString, WideString – was im Projekt wirklich zählt

Für die Migration ist entscheidend, welche Typen an Schnittstellen und in Kernfunktionen verwendet werden:

  • string: Seit Delphi 2009 ein UnicodeString (UTF-16, reference-counted, immutable semantics über Copy-on-Write).
  • AnsiString: Byte-String mit zugeordneter Codepage (je nach Delphi-Version kann eine Codepage mitgeführt werden). Geeignet, wenn eine externe Schnittstelle explizit eine bestimmte 8-Bit-Codierung verlangt.
  • UTF8String: In neueren Delphi-Versionen häufig als Alias/AnsiString mit UTF-8-Codepage; praktikabel für REST/JSON und viele Protokolle.
  • WideString: BSTR (COM), speicherverwaltet über SysAllocString; heute meist nur noch nötig für bestimmte COM-Interops.
  • PChar: Seit Unicode-Delphi PWideChar. Das ist einer der häufigsten Bruchpunkte bei Windows-API-Calls.

Werden diese Typen gemischt, entstehen Konvertierungen. Manche sind korrekt, manche sind überraschend: Eine Konvertierung ist nur dann „richtig“, wenn Sie wissen, welche Codepage an der Quelle anliegt und welche am Ziel erwartet wird.

UTF-16 intern, UTF-8 extern: ein praxistaugliches Leitbild

In Delphi-VCL-Anwendungen ist es oft sinnvoll, intern konsequent mit string (UTF-16) zu arbeiten. Extern (REST, Dateien, Messaging) dominiert in der Realität UTF-8. Eine robuste Linie lautet daher:

  • Intern: string/UnicodeString als Standard.
  • Grenzen: Beim Ein-/Ausgang explizit über TEncoding.UTF8 (oder definierte ANSI-Codepages) konvertieren.
  • Byte-basierte Verarbeitung: TBytes statt Strings.

Das reduziert implizite Konvertierungen und macht Verantwortlichkeiten prüfbar: „Wo wird aus Bytes Text, und mit welchem Encoding?“

Bestandsaufnahme: Wo Unicode in alten Delphi-Projekten typischerweise bricht

Bevor Sie Code anfassen, lohnt eine strukturierte Inventur. In der Unicode-Migration alter Delphi-Projekte sind die Fehlerquellen meist nicht gleichmäßig verteilt, sondern konzentrieren sich auf einige Hotspots.

1) Datenbankzugriff und Feldtypen (BDE, ADO, FireDAC)

Viele Altprojekte nutzen noch BDE oder ältere Datenzugriffsschichten. Hier sind die Probleme häufig:

  • Zuordnung von Datenbank-Charsets zu Delphi-Strings (ANSI vs. Unicode-Feldtypen).
  • „Text“ in BLOBs oder Memo-Feldern ohne definierte Kodierung.
  • SQL-Statements als Strings, die bei Umlauten/Unicode-Zeichen unterschiedlich interpretiert werden.

Wenn ohnehin Modernisierung ansteht, lässt sich eine Unicode-Migration gut mit einer Bereinigung des Datenzugriffs verbinden, z. B. Richtung BDE-Ablosung mit nativer Anbindung und klarer Charset-Konfiguration (etwa bei PostgreSQL oder MariaDB). Wichtig: Eine Migration sollte nicht automatisch eine Datenbankmigration erzwingen, aber die Schnittstelle zwischen DB und Delphi muss eindeutig sein.

2) Datei- und Stream-I/O: CSV, INI, proprietäre Formate, Import/Export

Ein Klassiker: Dateien wurden früher per AssignFile/ReadLn, TFileStream oder TStringList.LoadFromFile gelesen/geschrieben, ohne Encoding zu setzen. In Unicode-Delphi entscheidet dann Delphi heuristisch (BOM) oder nutzt Default-Encodings. Das führt zu:

  • falsch interpretierten Umlauten (ä, ö) in CSV/Logfiles,
  • fehlerhaften Längenangaben in proprietären Formaten,
  • Inkompatibilitäten zu externen Partnern, die ISO-8859-1 oder Windows-1252 erwarten.

Eine saubere Lösung ist, pro Dateiformat ein festes Encoding zu definieren und das in Code und Dokumentation zu verankern. Für CSV/JSON ist UTF-8 meistens der richtige Standard, für alte Schnittstellen manchmal Windows-1252. Entscheidend ist die Explizitheit.

3) Windows-API, PChar, Buffergrößen und Message-Handling

Viele Delphi-Anwendungen rufen WinAPI-Funktionen auf oder arbeiten mit Buffern. Häufige Bruchstellen:

  • Verwendung von PChar in Verbindung mit Funktionen, die ANSI- oder Wide-Varianten besitzen (…A/…W).
  • Buffergrößen werden in Bytes gerechnet, aber Char ist in UTF-16 2 Byte.
  • Pointer-Arithmetik und Record-Layouts, die auf 1-Byte-Chars basieren.

Hier ist präzises Refactoring nötig: entweder konsequent Wide-APIs nutzen oder bewusst die ANSI-Variante aufrufen und mit AnsiString/Codepage arbeiten. „Irgendwie kompiliert“ ist kein Qualitätskriterium.

4) COM, ActiveX, Office-Automation und Drittbibliotheken

COM-Interfaces arbeiten häufig mit BSTR (WideString). Alte Delphi-Versionen hatten andere Default-Strings, sodass Code „zufällig“ passte. In Unicode-Delphi entstehen oft doppelte Konvertierungen oder falsche Typannahmen in Wrappern. Drittbibliotheken sind ebenfalls kritisch: Manche liefern Callbacks als PAnsiChar, andere erwarten nullterminierte Byte-Strings.

Hier lohnt es sich, Abhängigkeiten zu klassifizieren: Welche Bibliothek ist Unicode-ready, welche nicht, und welche kann ersetzt oder gekapselt werden? Eine Kapselung ist oft der schnellste Weg, um Unicode-Altlasten in einen klar umrissenen Bereich zu verlagern.

Strategie: Unicode-Migration alter Delphi-Projekte als kontrolliertes Modernisierungsprogramm

Die migrationssicherste Vorgehensweise ist ein mehrstufiges Programm, das Risiken früh sichtbar macht und die Anwendung dabei lauffähig hält.

Schritt 1: Scope definieren und Code-Hotspots priorisieren

Nicht jeder Quelltext braucht sofort Anpassungen. Priorisieren Sie nach Datenfluss und Risiko:

  • Schnittstellen nach außen (REST-API, TCP/IP, Dateien, E-Mail, Druck/Reporting).
  • Datenzugriff (SQL, ORM/Datamodule, BDE/FireDAC-Schichten).
  • String-nahe Utility-Funktionen (Parser, Formatter, Encoder/Decoder).
  • Integrationen (COM, DLL-Imports, Hardware-Anbindungen).

Ergebnis sollte eine Liste sein, wo „Encoding eine Spezifikation“ ist. Diese Stellen werden später testbar gemacht.

Schritt 2: Compiler-/Projektoptionen und Warnungen bewusst scharfstellen

In vielen Projekten wurden Warnungen über Jahre abgeschaltet. Für eine Unicode-Migration ist das kontraproduktiv. Sinnvoll ist, Warnungen wieder zu aktivieren und Konvertierungswarnungen ernst zu nehmen. Zusätzlich hilft es, projektweit Regeln festzulegen, etwa: keine impliziten AnsiString-Konvertierungen an I/O-Grenzen, Nutzung von TEncoding bei Dateioperationen, keine „PChar-Tricks“ ohne klaren Kontext.

Schritt 3: „Encoding-Grenzen“ als technische Schicht einziehen

Ein praxistauglicher Architekturgriff ist die Einführung kleiner Adapter/Helper, die genau definieren, wie externe Daten rein und raus gehen. Beispiele:

  • CSV-Reader/-Writer: immer mit TEncoding.UTF8 (oder definierter Codepage) und klaren Separatorregeln.
  • REST-Client/Server: JSON immer als UTF-8-Bytes, Header korrekt setzen, Body nicht „stringbasiert“ streamen.
  • Windows-API-Wrapper: zentrale Funktionen, die Wide/Ansi sauber kapseln.

So verhindern Sie, dass sich „Encoding-Entscheidungen“ quer durch die Codebasis verteilen.

Typische Code-Fallen und wie man sie sauber behebt

Length, SizeOf, ByteLength: wenn Zeichenlänge und Bytegröße auseinanderlaufen

In ANSI-Zeiten wurde Length(s) oft als Byteanzahl missbraucht. In UTF-16 ist das falsch. Wenn Sie Byte-Arrays benötigen, konvertieren Sie explizit:

  • Für UTF-8: TEncoding.UTF8.GetBytes(s)
  • Für definierte ANSI-Codepage: TEncoding.GetEncoding(1252).GetBytes(s) (nur, wenn fachlich korrekt)

Für Buffergrößen bei API-Calls gilt: Prüfen, ob die Funktion Zeichen- oder Byteeinheiten erwartet. Viele Wide-APIs erwarten Zeichenanzahl, nicht Bytes. Dokumentation und Signatur entscheiden, nicht Intuition.

PAnsiChar vs. PWideChar: DLL-Imports und externe Protokolle

Bei DLL-Imports ist die Gefahr groß, dass Signaturen im Delphi-Code nicht mehr passen. Legen Sie fest, was die DLL erwartet:

  • Erwartet die DLL UTF-8? Dann ist die Übergabe als PAnsiChar(UTF8String) üblich, aber Sie müssen Lebenszeit und Nullterminierung kontrollieren.
  • Erwartet sie UTF-16? Dann nutzen Sie PWideChar und Wide-Strings.

In jedem Fall sollten die Imports in einer separaten Unit kapselt werden, damit sich die String-Politik nicht im gesamten Projekt verteilt.

Formatierung, Case-Umwandlung, Vergleich: Locale und Normalisierung

Unicode bringt auch semantische Themen: Groß-/Kleinschreibung ist nicht in allen Sprachen trivial, und Zeichen können verschiedene Normalformen haben. In typischen Unternehmensanwendungen ist das weniger kritisch als in Consumer-Textverarbeitung, aber es betrifft:

  • Sortierung und Filterung (z. B. in Grids oder Suchfunktionen),
  • Case-insensitive Vergleiche für Schlüsselwerte,
  • Generierung von Dateinamen oder Identifiern.

Wichtig ist eine klare Regel: Was sind „Schlüssel“ (z. B. Artikelnummern, Kundencodes), die ASCII-nah bleiben sollten, und was sind „Texte“, die voll Unicode-fähig sein müssen? Diese Trennung reduziert Folgefehler.

GUI/Reporting: Fonts, Druck, PDF und Komponentenverhalten

VCL ist seit den Unicode-Versionen grundsätzlich Unicode-fähig, aber die Praxis hängt an Komponenten und Ausgabepfaden. Risiken entstehen bei:

  • älteren Report-Engines oder PDF-Generatoren, die ANSI annehmen,
  • Barcode-/Label-Druck, der bestimmte Codepages benötigt,
  • Hardcodierten Fonts oder Zeichensätzen.

Planen Sie früh Tests mit realen Beispieldaten (Namen, Orte, Sonderzeichen, nicht-lateinische Schriften, wenn relevant). Der Wert liegt weniger im „kann Unicode“, sondern im Nachweis: „Dieser Output ist in unserem Kontext korrekt.“

Daten und Persistenz: Unicode endet nicht beim Code

Datenbank-Charsets und Collations sauber festlegen

Eine Unicode-Migration ist nur dann stabil, wenn Datenbanken und Treiber korrekt konfiguriert sind. Beispiele:

  • Bei PostgreSQL ist UTF-8 im Regelfall Standard; dennoch müssen Client-Encoding und Treiberverhalten geprüft werden.
  • Bei SQL Server ist die Unterscheidung zwischen VARCHAR und NVARCHAR relevant; falsche Spaltenwahl kann Zeichen verlieren.
  • Bei MariaDB/MySQL sind Charset/Collation (z. B. utf8mb4) entscheidend, damit 4-Byte-Zeichen nicht abgeschnitten werden.

Im Delphi-Code sollten Parameter und Feldtypen so genutzt werden, dass Unicode nicht auf dem Weg „zurückkonvertiert“ wird. FireDAC bietet hier meist bessere Kontrolle als sehr alte Zugriffsschichten.

Legacy-Dateiformate: Migrationsregeln statt stiller Konvertierung

Wenn Ihre Anwendung über Jahre Dateien erzeugt hat (Exportformate, Archivdateien, proprietäre Strukturen), müssen Sie definieren:

  • Welche Bestandsdateien bleiben „wie sie sind“ und werden beim Lesen korrekt interpretiert?
  • Welche Formate werden auf UTF-8 angehoben?
  • Gibt es Versionsfelder/Headers, um neue und alte Dateien eindeutig zu unterscheiden?

Stille Konvertierung ohne Kennzeichnung ist riskant, weil Fehler oft erst spät auffallen. Besser: versionieren, klar erkennen, gezielt migrieren.

Qualitätssicherung: Tests, die Unicode-Probleme wirklich finden

Unicode-Fehler sind häufig datenabhängig. Deshalb reichen „Happy Path“-Tests nicht aus. Sinnvoll ist ein Testset, das die problematischen Stellen abdeckt:

  • Roundtrip-Tests: Import → Verarbeitung → Export, danach Byte-genauer Vergleich (bei definierten Formaten).
  • DB-Roundtrip: Schreiben/Lesen von Texten mit Umlauten, Akzenten und ggf. nicht-lateinischen Zeichen; Prüfung auf Gleichheit.
  • Schnittstellen-Tests: REST-Requests als UTF-8, Header, JSON-Escaping, Logging.
  • Regression: Altdaten und typische Benutzerfälle reproduzieren, vor allem bei Suche, Filter, Sortierung.

Für B2B-Systeme ist außerdem relevant, dass Fehler beobachtbar werden: Logging sollte Encodings nicht zerstören. Wer Logs als ANSI schreibt, verliert im Fehlerfall genau die Information, die man braucht.

Planung und Aufwand: Was die Komplexität wirklich treibt

Der Aufwand der Unicode-Migration alter Delphi-Projekte hängt weniger von „Zeilen Code“ ab, sondern von Kopplungen und externen Abhängigkeiten:

  • Viele Integrationen (DLLs, COM, Geräte, ERP/DMS/CRM) erhöhen Prüfaufwand, weil Encodings an jeder Grenze relevant sind.
  • Historische Formate (alte Exporte, kundenspezifische CSVs) erfordern Migrationsregeln und Kompatibilitätsstrategien.
  • Gemischte Delphi-Versionen oder mehrere Produkte aus einem Code-Stamm erhöhen Koordinationsbedarf.
  • Alte Datenzugriffsschichten (z. B. BDE) können Unicode indirekt blockieren und eine Modernisierung nahelegen.

In der Praxis hat sich ein Vorgehen bewährt, das Unicode zuerst im Kern und in den kritischsten Datenflüssen stabilisiert. Danach kann man schrittweise Module nachziehen. Das reduziert Risiko und verhindert lange „Big Bang“-Phasen ohne Release.

Einordnung in Modernisierungspfade: REST, Services, Multiplattform

Unicode ist häufig ein Grundpfeiler, wenn Bestandssoftware modernisiert werden soll. Typische Anschlussfragen sind:

  • REST-Server oder REST-API nachrüsten (JSON/UTF-8 sauber behandeln).
  • Windows-Services oder Linux-Services stabil betreiben (Logging, Konfigdateien, Protokolle).
  • Schrittweise UI-Modernisierung in VCL, später ggf. Multiplattform-Clients.

Wichtig ist die Reihenfolge: Wenn Sie neue Schnittstellen bauen, sollten Encoding-Regeln vorher feststehen. Eine Unicode-Migration „nebenbei“ während der Schnittstellenentwicklung führt sonst zu schwer prüfbaren Fehlerbildern, weil Ursache und Wirkung vermischt werden.

Für die interne Verlinkung im Magazin bietet sich an, angrenzende Themen wie Delphi-Modernisierung, FireDAC-Datenzugriff oder Architektur von REST-Servern als vertiefende Artikel zu platzieren, sodass Leser gezielt in den nächsten technischen Schritt springen können.

Fazit: Unicode-Migration ist ein Risiko-Thema – mit der richtigen Methode wird es planbar

Die Unicode-Migration alter Delphi-Projekte ist kein kosmetisches Upgrade, sondern eine Korrektur grundlegender Annahmen über Text, Bytes und Schnittstellen. Wer strukturiert vorgeht, gewinnt jedoch mehr als „Umlaute funktionieren wieder“: Datenflüsse werden eindeutiger, Integrationen robuster, und spätere Modernisierung (z. B. REST-Server, Services, Datenbankbereinigung) wird einfacher, weil Encodings nicht mehr implizit „irgendwo“ passieren.

Wenn Sie für Ihre Delphi-Anwendung einen konkreten Migrationsplan, eine Risikoanalyse der Hotspots oder Unterstützung bei der Umsetzung benötigen, ist der schnellste nächste Schritt ein technisches Erstgespräch über Ihre Rahmenbedingungen und Abhängigkeiten: Kontakt aufnehmen.

Im fachlichen Umfeld spielen auch Delphi Unicode Migration und Delphi Ansi Zu Unicode eine wichtige Rolle, wenn Integrationen, Datenflüsse und Weiterentwicklung sauber zusammenspielen müssen.

Projekt oder Modernisierungsvorhaben mit Net-Base besprechen.

Bejegyzés megosztása

Ezt a bejegyzést közvetlenül megosztani

LinkedIn, X, XING, Facebook, WhatsApp és E-Mail azonnal elérhetők. Instagramra a linket és a rövid szöveget közvetlenül előkészítjük.

E-mail

Az Instagram egy új lapon nyílik meg. A link és a rövid szöveg előzetesen a vágólapra másolódik.