Net-Base Časopis

19.04.2026

Migracija starih Delphi projekata na Unicode: zamke, strategija i čista implementacija

Mnoge postojeće Delphi aplikacije još uvijek koriste ANSI nizove. Migracija na Unicode tada je više od podešavanja kompajlera: ona utiče na pristup podacima, sučelja, izvještaje, biblioteke trećih strana i testove. Ovaj članak prikazuje praktičan put migracije – uključujući...

19.04.2026

Unicode-migracija starih Delphi-projekata u mnogim preduzećima je neophodan korak, jer postojeće aplikacije inače kod internacionalnih podataka, modernih operativnih sistema, integracija i novih interfejsa sve češće nailaze na ograničenja. U praksi to rijetko znači „Recompile i gotovo“. Delphi je od Unicode-verzija (od Delphi 2009) izvršio temeljne promjene u standardnim string-tipovima. Time su se pomjerila očekivanja o kodiranju znakova, rasporedu u memoriji i potpisima API-ja. Ko to podcijeni, proizvodi postepene greške u podacima, pokvarene exporte, nejasne support-slučajeve i sigurnosne rizike.

Ovaj članak pruža tehnički utemeljenu proceduru: kako analizirati postojeći sistem, razumno odrediti opseg, smanjiti rizike na hotspotovima (baze podataka, fajlovi, Windows-APIs, COM, REST-servisi) i osigurati migraciju tako da rad sistema i dalji razvoj mogu teći paralelno. Fokus je na Delphi-tipičnim zamkama u VCL-aplikacijama, servisima i interfejsima – s pogledom na puteve modernizacije u koje se kasnije mogu uklopiti i teme poput BDE-zamjene s nativnim priključkom, REST-servera ili multiplatformskog rada.

Zašto je Unicode-prelazak u Delphi često „veći nego što se misli“

U klasičnim verzijama Delphi tip string je bio ANSI-string (ovisno o sistemskoj codepage). Od Delphi 2009 string je standardno UnicodeString (UTF-16). Istovremeno su mnoge biblioteke i VCL-klase prešle na Wide-API-je. To je generalno pozitivno jer robustno podržava internacionalne znakove. Ali: legacy-kod je često tokom godina nastao pod pretpostavkama „1 znak = 1 bajt“, „PChar je PAnsiChar“ ili „Length() odgovara broju bajtova”.

Tipični uzroci zbog kojih migracije postaju zahtjevnije:

  • Implicitne konverzije prolaze, ali mijenjaju podatke (posebno kod fajlova, interfejsa ili polja tipa BLOB/Text u bazama).
  • Bajt-orijentirani kod (streamovi, bufferi, hashing, enkripcija) postaje neprimjetno netačan kada se sadržaj stringova interpretira kao bajtovi.
  • Komponente trećih strana su ponekad ANSI-only ili koriste vlastite string-tipe i callback-e.
  • Spoljašnji kontekst (Windows-APIs, COM, štampa/reporting, EDI, CSV, XML/JSON) očekuje određena kodiranja.

Cilj zato ne bi trebao biti „što manje mijenjati“, nego ciljano mijenjati tamo gdje treba jasno definirati tokove podataka i kodiranja. Čista Unicode-migracija je i prilika da se nedoređene granice kodiranja napokon dokumentuju i testiraju.

Tehničke osnove: Delphi-stringtipovi, encodingi i njihove nuspojave

string, UnicodeString, AnsiString, WideString – šta u projektu zaista znači

Za migraciju je presudno koji se tipovi koriste na interfejsima i u ključnim funkcijama:

  • string: od Delphi 2009 UnicodeString (UTF-16, reference-counted, immutable semantika preko Copy-on-Write).
  • AnsiString: bajt-string s pridruženom codepage (ovisno o verziji Delphi može nositi informaciju o codepage). Pogodan kad eksterni interfejs eksplicitno zahtijeva određeno 8-bitno kodiranje.
  • UTF8String: u novijim verzijama Delphi često alias/AnsiString s UTF-8 codepage; praktičan za REST/JSON i mnoge protokole.
  • WideString: BSTR (COM), upravljanje memorijom preko SysAllocString; danas obično potreban samo za određene COM-interop-e.
  • PChar: od Unicode-Delphi PWideChar. To je jedna od najčešćih tačaka preloma kod Windows-API poziva.

Ako se ovi tipovi miješaju, nastaju konverzije. Neke su ispravne, neke iznenađujuće: konverzija je „tačna“ samo ako znate koju codepage ima izvor i šta cilj očekuje.

Interno UTF-16, eksterno UTF-8: praktično vodilo

U VCL-aplikacijama baziranim na Delphi često je smisleno interno dosljedno raditi s string (UTF-16). Eksterno (REST, fajlovi, messaging) u praksi dominira UTF-8. Robusna linija glasi:

  • Interno: string/UnicodeString kao standard.
  • Granice: pri ulazu/izlazu eksplicitno konvertovati preko TEncoding.UTF8 (ili definirane ANSI-codepage-e).
  • Bajt-bazirana obrada: TBytes umjesto String-ova.

To smanjuje implicitne konverzije i čini odgovornosti provjerljivim: „Gdje se bajtovi pretvaraju u tekst i koje je kodiranje?“

Inventar: gdje Unicode u starim Delphi-projektima tipično puca

Prije nego što dirate kod, vrijedi strukturirana inventura. U Unicode-migracijama starih Delphi-projekata izvori grešaka obično nisu ravnomjerno raspoređeni, nego se koncentriraju na nekoliko hotspotova.

1) Pristup bazi podataka i tipovi polja (BDE, ADO, FireDAC)

Mnogi stari projekti još koriste BDE ili starije slojeve za pristup podacima. Problemi su često:

  • Povezivanje charset-a baze s Delphi-stringovima (ANSI nasuprot Unicode-polju).
  • „Tekst“ u BLOB-ovima ili memo-poljima bez definirane enkodacije.
  • SQL-naredbe kao String-ovi koji se pri umlautima/Unicode-znakovima različito interpretiraju.

Ako ionako planirate modernizaciju, Unicode-migraciju je dobro kombinovati s čišćenjem pristupa podacima, npr. u smjeru BDE-Ablosung mit nativer Anbindung i jasne konfiguracije charset-a (kao kod PostgreSQL ili MariaDB). Važno: migracija ne mora automatski iznuditi promjenu baze, ali sučelje između DB i Delphi mora biti nedvosmisleno.

2) Fajl- i stream-I/O: CSV, INI, proprietarni formati, import/export

Klasičan slučaj: fajlovi su ranije čitani preko AssignFile/ReadLn, TFileStream ili TStringList.LoadFromFile bez postavljenog encodinga. U Unicode-Delphi tada Delphi heuristički odlučuje (BOM) ili koristi default-encoding. To dovodi do:

  • pogrešno interpretiranih umlauta (ä, ö) u CSV/log fajlovima,
  • netočnih informacija o dužini u proprietarnim formatima,
  • nekompatibilnosti s vanjskim partnerima koji očekuju ISO-8859-1 ili Windows-1252.

Čisto rješenje je definirati po formatu fajla fiksno kodiranje i to zabilježiti u kodu i dokumentaciji. Za CSV/JSON je UTF-8 najčešće ispravan standard, za stare interfejse ponekad Windows-1252. Presudna je eksplicitnost.

3) Windows-API, PChar, veličine buffera i rukovanje porukama

Mnoge Delphi-aplikacije zovu WinAPI funkcije ili rade s bufferima. Česte točke loma:

  • korištenje PChar u vezi s funkcijama koje imaju ANSI- ili Wide-varijante (…A/…W).
  • veličine buffera se računaju u bajtovima, a Char u UTF-16 zauzima 2 bajta.
  • aritmetika pokazivača i layout record-a koji su zasnovani na 1-bajtnih char-ovima.

Ovdje je potrebno precizno refaktoriranje: ili dosljedno koristiti Wide-API-je ili svjesno pozivati ANSI-varijantu i raditi s AnsiString/codepage-om. „Negdje se kompajlira“ nije kriterij kvaliteta.

4) COM, ActiveX, Office-automation i biblioteke trećih strana

COM-interface-i često rade s BSTR (WideString). Stare verzije Delphi imale su drugačije default-stringove, pa je kod „slučajno“ radio. U Unicode-Delphi često nastaju duple konverzije ili pogrešne pretpostavke tipova u wrapper-ima. Biblioteke trećih strana su također kritične: neke vraćaju callback-e kao PAnsiChar, druge očekuju null-terminirane bajt-stringove.

Vrijedi klasificirati ovisnosti: koja biblioteka je Unicode-ready, koja nije i koja se može zamijeniti ili enkapsulirati? Enkapsulacija je često najbrži put da se Unicode-legacy ograniči na jasno definiranu zonu.

Strategija: Unicode-migracija starih Delphi-projekata kao kontrolisani program modernizacije

Najjača migraciona procedura je višestupanjski program koji rizike čini vidljivima rano i drži aplikaciju u radu.

Korak 1: Definisati scope i prioritizovati kod-hotspote

Nije svaki izvorni kod odmah za prilagodbu. Prioritizirajte prema protoku podataka i riziku:

  • Interfejsi prema van (REST-API, TCP/IP, fajlovi, e-mail, štampa/reporting).
  • Pristup podacima (SQL, ORM/Datamodule, BDE/FireDAC-slojevi).
  • String-bliske utility-funkcije (parseri, formatteri, encoder/decoderi).
  • Integracije (COM, DLL-importi, priključci na hardver).

Rezultat treba biti lista mjesta gdje „encoding ima specifikaciju“. Ta mjesta će kasnije postati testabilna.

Korak 2: Svjesno oštrije postaviti compiler-/projekt-opcije i upozorenja

U mnogim projektima su upozorenja godinama isključena. Za Unicode-migraciju je to kontraproduktivno. Podesite upozorenja ponovo i shvatite konverzijska upozorenja ozbiljno. Također pomaže definirati projektno pravilo, npr.: nema implicitnih AnsiString-konverzija na I/O-granicama, upotreba TEncoding pri fajl-operacijama, bez „PChar-trikova“ bez jasnog konteksta.

Korak 3: Uvesti „granice enkodiranja“ kao tehnički sloj

Praktičan arhitektonski pristup je uvođenje malih adaptera/helper-a koji precizno određuju kako vanjski podaci ulaze i izlaze. Primjeri:

  • CSV-reader/-writer: uvijek s TEncoding.UTF8 (ili definiranim codepage-om) i jasnim pravilima o separatorima.
  • REST-klijent/server: JSON uvijek kao UTF-8 bajtovi, headeri pravilno postavljeni, body ne streamovati „string-based“.
  • Windows-API-wrapper: centralne funkcije koje Wide/Ansi čisto enkapsuliraju.

Time sprječavate da se „odlučivanja o encodingu“ razliju po cijeloj bazi koda.

Tipične kod-pandreke i kako ih uredno popraviti

Length, SizeOf, ByteLength: kada se broj znakova i broj bajtova razilaze

U ANSI-vremenima se Length(s) često zloupotrebljavao kao broj bajtova. U UTF-16 je to netačno. Ako trebate bajt-niz, eksplicitno konvertujte:

  • Za UTF-8: TEncoding.UTF8.GetBytes(s)
  • Za definiranu ANSI-codepage: TEncoding.GetEncoding(1252).GetBytes(s) (samo ako je strogo ispravno iz domene)

Za veličine buffera kod API-poziva provjerite očekuje li funkcija jedinice znakova ili bajtova. Mnogi Wide-API-ji očekuju broj znakova, ne bajtova. Dokumentacija i potpis funkcije odlučuju, a ne intuicija.

PAnsiChar vs. PWideChar: DLL-importi i eksterni protokoli

Prilikom DLL-importa postoji visok rizik da potpisi u Delphi-kodu više ne odgovaraju. Odredite što DLL očekuje:

  • Očekuje li DLL UTF-8? Tada je uobičajeno proslijediti PAnsiChar(UTF8String), ali morate kontrolisati životni vijek i null-terminaciju.
  • Očekuje li UTF-16? Tada koristite PWideChar i Wide-stringove.

U svakom slučaju import-e držite u zasebnoj unitu, da se politika stringova ne rasprši po cijelom projektu.

Formatiranje, promjena veličine slova, poređenje: lokalitet i normalizacija

Unicode donosi i semantičke teme: upper/lowercase nije trivijalno u svim jezicima, a znakovi mogu imati različite normalne forme. U tipičnim enterprise-aplikacijama to je manje kritično nego u obradi tekstova za korisnike, ali pogađa:

  • sortiranje i filtriranje (npr. u gridovima ili pretragama),
  • case-insensitive usporedbe za ključne vrijednosti,
  • generisanje imena fajlova ili identifikatora.

Važno je imati jasnu politiku: šta su „ključevi“ (npr. šifre artikala, kodovi kupaca) koji bi trebali ostati ASCII-niski, a šta su „teksti“ koji moraju biti u potpunosti Unicode-kompatibilni? Ta podjela smanjuje kasnije greške.

GUI/Reporting: fontovi, štampa, PDF i ponašanje komponenti

VCL je od Unicode-verzija principijelno Unicode-spreman, ali praksa ovisi o komponentama i izlaznim putem. Rizici nastaju kod:

  • starijih report-engine-a ili PDF-generatora koji prihvataju ANSI,
  • barcode/label-štampe koja zahtijeva određene codepage-e,
  • hardcodiranih fontova ili setova znakova.

Planirajte rano testove s realnim primjerima podataka (imena, mjesta, posebni znakovi, ne-latinična pisma ako su relevantna). Vrijednost je manje u „može Unicode“, a više u dokazivanju: „Ovaj izlaz je u našem kontekstu ispravan.“

Podaci i persistencija: Unicode ne završava u kodu

Ispravno definirati charset-e i collation-e u bazama

Unicode-migracija je stabilna samo ako su baze podataka i drajveri pravilno konfigurirani. Primjeri:

  • Za PostgreSQL je UTF-8 obično standard; ipak treba provjeriti client-encoding i ponašanje drajvera.
  • Za SQL Server je razlika između VARCHAR i NVARCHAR relevantna; krivi tip kolone može dovesti do gubitka znakova.
  • Za MariaDB/MySQL su charset/collation (npr. utf8mb4) presudni da 4-bajtni znakovi ne budu odrezani.

U Delphi-kodu koristite parametre i tipove polja tako da se Unicode ne „vrati“ u neku konverziju na putu. FireDAC obično nudi bolju kontrolu od vrlo starih pristupnih slojeva.

Legacy-fajlformati: pravila migracije umjesto tihih konverzija

Ako vaša aplikacija godinama proizvodi fajlove (export formati, arhivske datoteke, proprietarne strukture), morate definirati:

  • Koje postojeće fajlove ostavljate „kako jesu“ i kako će se pri čitanju ispravno interpretirati?
  • Koje formate podižete na UTF-8?
  • Postoje li polja/hederi verzije da se novi i stari fajlovi jasno razlikuju?

Tiha konverzija bez oznake je rizična jer se greške najčešće pokažu kasno. Bolje: verzionirati, jasno detektovati i ciljano migrirati.

Osiguranje kvalitete: testovi koji zaista nalaze Unicode-probleme

Unicode-greške su često ovisne o podacima. Zato „happy path“ testovi nisu dovoljni. Korisno je testset koji pokriva problematična mjesta:

  • Roundtrip-testovi: import → obrada → export, nakon toga bajt-na-bajt poređenje (kod definiranih formata).
  • DB-roundtrip: zapis/čitanje tekstova s umlautima, akcentima i po potrebi ne-latiničnim znakovima; provjera jednakosti.
  • Interfejs-testovi: REST-requesti kao UTF-8, headeri, JSON-escaping, logging.
  • Regresija: reproducirati stare podatke i tipične korisničke scenarije, posebno pri pretraživanju, filtriranju, sortiranju.

Za B2B-sisteme je također važno da su greške uočljive: logging ne smije uništavati kodiranje. Ako logove zapisujete kao ANSI, u slučaju greške izgubite upravo informacije koje su vam potrebne.

Planiranje i napor: šta zaista povećava složenost

Napor Unicode-migracije starih Delphi-projekata manje zavisi od „broja linija koda“, a više od sprega i vanjskih ovisnosti:

  • Mnoštvo integracija (DLL-i, COM, uređaji, ERP/DMS/CRM) povećava opseg provjera jer je na svakoj granici važno provjeriti encoding.
  • Historijski formati (stari exporti, klijentski CSV-ovi) zahtijevaju pravila migracije i strategije kompatibilnosti.
  • Pomiješane Delphi-verzije ili više proizvoda iz istog kodnog stabla povećavaju koordinacijski trošak.
  • Stari slojevi za pristup podacima (npr. BDE) mogu indirektno blokirati Unicode i upućuju na potrebu modernizacije.

U praksi se pokazao pristup koji prvo stabilizira Unicode u jezgru i u kritičnim tokovima podataka. Nakon toga se modularno nadograđuju ostali dijelovi. To smanjuje rizik i izbjegava duge „big bang“ faze bez releasa.

Usklađivanje s modernizacijskim putevima: REST, servisi, multiplatforma

Unicode je često temelj kad se postojeći softver želi modernizirati. Tipična pitanja koja slijede su:

  • REST-server ili REST-API dodati (JSON/UTF-8 pravilno tretirati).
  • Stabilno upravljanje Windows-servisima ili Linux-servisima (logging, konfiguracijski fajlovi, protokoli).
  • Postepena modernizacija UI-ja u VCL, kasnije eventualno multiplatform klijenti.

Bitan je redoslijed: kad gradite nove interfejse, pravila o encodingu trebaju biti unaprijed definirana. Unicode-migracija „usput“ tokom razvoja interfejsa stvara teško testabilne greške jer se uzrok i posljedica pomiješaju.

Za internu poveznicu u magazinu prikladno je postaviti povezane teme kao što su Delphi-modernizacija, FireDAC-pristup podacima ili arhitektura REST-servera kao produbljujuće članke, tako da čitaoci mogu direktno nastaviti na sljedeći tehnički korak.

Zaključak: Unicode-migracija je pitanje rizika – uz pravu metodu postaje planabilna

Unicode-migracija starih Delphi-projekata nije kozmetički update, nego ispravka temeljnih pretpostavki o tekstu, bajtovima i interfejsima. Onaj koji postupa strukturirano ipak dobije više od „ponovno rade umlauti“: tokovi podataka postaju jasniji, integracije robusnije, a kasnija modernizacija (npr. REST-serveri, servisi, čišćenje baza) jednostavnija, jer se kodiranja više ne odvijaju implicitno „negdje“.

Ako za vašu Delphi-aplikaciju trebate konkretan plan migracije, analizu rizika hotspota ili podršku pri implementaciji, najbrži sljedeći korak je tehnički inicijalni razgovor o vašim okvirima i ovisnostima: Kontakt aufnehmen.

U stručnom kontekstu Delphi Unicode Migration i Delphi Ansi Zu Unicode također igraju važnu ulogu kad integracije, tokovi podataka i dalji razvoj trebaju funkcionisati zajedno.

Projekt oder Modernisierungsvorhaben mit Net-Base besprechen.

Podijeli objavu

Ovu objavu direktno proslijediti

LinkedIn, X, XING, Facebook, WhatsApp i e-pošta su odmah dostupni. Za Instagram pripremamo link i kratak tekst.

E-pošta

Instagram se otvara u novom tabu. Link i kratak tekst se prethodno kopiraju u međuspremnik.