Net-Base Магазин

19.04.2026

Unicode-миграција старих Delphi пројеката: замке, стратегија и чиста имплементација

Многе Delphi-постојеће апликације и даље раде са ANSI низовима. Unicode миграција је тада више од компајлерског прекидача: она утиче на приступ подацима, интерфејсе, извештаје, библиотеке трећих страна и тестове. Овај чланак показује практичан пут миграције – укључујући...

19.04.2026

Unicode миграција старих Delphi-пројеката је у многим предузећима неопходан корак, јер иначе постојеће апликације све чешће наилазе на ограничења при руковању интернационалним подацима, модерним оперативним системима, интеграцијама и новим интерфејсима. У пракси то ретко значи „Recompile und fertig“. Delphi је од Unicode-верзија (од Delphi 2009) извршио фундаменталне измене у стандардним типовима string. То помера претпоставке о кодирању знакова, распореда у меморији и API сигнатурама. Ко то потцени, ствара постепене грешке у подацима, покварене експорте, нејасне случајеве подршке и безбедносне ризике.

Овај чланак даје технички обазрив приступ: како анализирати постојеће стање, смислено одредити обим, смањити ризике на критичним местима (Datenbanken, Dateien, Windows-APIs, COM, REST-Services) и обезбедити миграцију тако да рад система и даљи развој могу течно да се наставе паралелно. Фокус је на Delphi-типичним замкама у VCL апликацијама, сервисима и интерфејсима — са погледом на модернизационе путеве у које се касније могу уклопити теме попут BDE-Ablösung mit nativer Anbindung, REST-Server или мултиплатформених решења.

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

У класичним Delphi верзијама string је био ANSI-String (у зависности од системске кодне странице). Од Delphi 2009 string је подразумевано UnicodeString (UTF-16). Истовремено су бројне библиотеке и VCL класе пребачене на Wide-API-је. То је у основи позитивно јер стабилно подржава међународне знакове. Међутим: наследни код често је нарастао око претпоставки „1 знак = 1 бајт“, „PChar је PAnsiChar“ или „Length() одговара броју бајтова“.

Типични разлози због којих миграције постају захтевније:

  • Имплицитне конверзије пролазе, али мењају податке (посебно код датотека, интерфејса или BLOB/TEXT поља у базама).
  • Битно оријентисани код (стримови, бафери, хеширање, шифровање) постаје погрешан ако се садржај string-а тумачи као низ бајтова.
  • Треће компоненте су делом ANSI-only или користе своје типове string-а и callback-ове.
  • Спољни контекст (Windows-APIs, COM, штампа/репортинг, EDI, CSV, XML/JSON) очекује специфична кодирања.

Циљ не треба бити „што мање мењати“, већ намерно мењати тамо где је неопходно дефинисати токове података и кодирања. Чиста Unicode миграција је и прилика да се неодређене границе кодирања коначно документују и тестирају.

Technische Grundlagen: Delphi-Stringtypen, Encodings und ihre Nebenwirkungen

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

За миграцију је пресудно који се типови користе на интерфејсима и у кључним функцијама:

  • string: Од Delphi 2009 подразумевано UnicodeString (UTF-16, reference-counted, immutable semantics преко Copy-on-Write).
  • AnsiString: бајт-стринг са придруженом codepage (у зависности од верзије Delphi може се чувати информација о codepage). Прикладан кад спољни интерфејс захтева конкретно 8-битно кодирање.
  • UTF8String: У новијим верзијама Delphi често као alias/AnsiString са UTF-8 codepage; практичан за REST/JSON и многе протоколе.
  • WideString: BSTR (COM), меморијски управљан преко SysAllocString; данас углавном потребан за одређене COM-interop сценарије.
  • PChar: Од Unicode-Delphi PWideChar. То је једна од најчешћих тачака ломљења при Windows-API позивима.

Када се ови типови међусобно мешају, настају конверзије. Некe су коректне, неке изненађујуће: конверзија је исправна само ако знате која codepage стоји на извору и која се очекује на циљу.

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

У VCL апликацијама често је практично унутрашње стање доследно водити као string (UTF-16). Споља (везе, датотеке, messaging) у пракси доминира UTF-8. Робусно правило гласи:

  • Интерно: string/UnicodeString као стандард.
  • Граничне тачке: при улазу/излазу експлицитно конвертовати преко TEncoding.UTF8 (или дефинисаних ANSI-codepage).
  • Бит-оријентисана обрада: TBytes уместо String-ова.

То смањује имплицитне конверзије и чини одговорности проверљивим: „Где се бајтови претварају у текст и којим кодирањем?“

Bestandsaufnahme: Wo Unicode in alten Delphi-Projekten typischerweise bricht

Пре него што дирате код, вреди спровести структурисану инвентаризацију. У Unicode миграцији старих Delphi пројеката изворе грешака обично нису равномерно распоређени, већ концентрисани на неколико критичних места.

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

Многи старе пројекти још користе BDE или старије слојеве за приступ бази. Чести проблеми су:

  • Усклађивање charset-ова базе са Delphi-string типовима (ANSI vs. Unicode поља).
  • „Текст“ у BLOB-овима или memo-полјима без дефинисаног кодирања.
  • SQL-наредбе као String-ови који се код Umlaut-а/Unicode знакова различито тумаче.

Кад већ радите модернизацију, Unicode миграцију је логично повезати са уређивањем приступа бази, нпр. према BDE-Ablosung mit nativer Anbindung и јасном конфигурацијом charset-а (као код PostgreSQL или MariaDB). Важно: миграција не мора нужно да наметне миграцију базе, али интерфејс између DB и Delphi мора бити недвосмислен.

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

Класик: датотеке су раније читане/писане преко AssignFile/ReadLn, TFileStream или TStringList.LoadFromFile без подешеног енкодинга. У Unicode-Delphi тада компајлер/рантајм илите heuristisch (BOM) или користи подразумевана кодирања. То води до:

  • погрешно интерпретираних Umlaut-ова (ä, ö) у CSV/лог фајловима,
  • погрешних вредности дужине у власничким форматима,
  • некомпатибилности са спољним партнерима који очекују ISO-8859-1 или Windows-1252.

Чисто решење је дефинисати за сваки формат фиксно кодирање и то записати у коду и документацији. За CSV/JSON UTF-8 је најчешће правилан стандард, за старе интерфејсе понекад Windows-1252. Кључна је експлицитност.

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

Много Delphi апликација позива WinAPI функције или ради са баферима. Чести ломни моменти:

  • Користење PChar уз функције које имају ANSI или Wide варијанте (…A/…W).
  • Величине бафера се рачунају у бајтовима, али Char у UTF-16 заузима 2 бајта.
  • Pointer-arithmetik и Record-Layout-ови базирани на 1-бајт знаковима.

Овде је потребан прецизан рефакторинг: или доследно користити Wide-API-је, или намерно позивати ANSI-варaнту и радити са AnsiString/Codepage. „Irgendwie kompiliert“ није критеријум квалитета.

4) COM, ActiveX, Office-Automation und Drittbibliotheken

COM интерфејси често раде са BSTR (WideString). У старим Delphi верзијама подразумевани string-ови су били другачији, па је код „случајно“ радио. У Unicode-верзијама често настају двоструке конверзије или погрешне претпоставке у wrapper-има. Треће библиотеке су такође критичне: неке дају callback-ове као PAnsiChar, друге очекују нул-терминиране бајт-низове.

Вреди класификовати зависности: која библиотека је Unicode-ready, која није, и која може бити замењена или капсулована? Капсулација је често најбржи начин да се Unicode наслеђе смести у јасно ограничен слој.

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

Најсигурнији приступ миграцији је вишестепени програм који рано открива ризике и задржава апликацију у радном стању.

Schritt 1: Scope definieren und Code-Hotspots priorisieren

Не мора сваки изворни код одмах да се мења. Приоритет дајте према току података и ризику:

  • Интерфејси према споља (REST-API, TCP/IP, датотеке, е-пошта, штампа/репортинг).
  • Приступ подацима (SQL, ORM/Datamodule, BDE/FireDAC слојеви).
  • Утилити функције блиске string-овима (парсери, форматирање, енкодер/декодер).
  • Интеграције (COM, DLL-Imports, хардверске везе).

Резултат треба да буде листа места где „Encoding треба да буде спецификација“. Та места се касније чине тестабилним.

Schritt 2: Compiler-/Projektoptionen und Warnungen bewusst scharfstellen

У многим пројектима су упозорења годинама искључена. За Unicode миграцију то је контрапродуктивно. Паметно је поново укључити упозорења и схватити конверзиона упозорења озбиљно. Такође помаже дефинисање пројектних правила, нпр.: без имплицитних AnsiString-конверзија на I/O границама, коришћење TEncoding при радњама над датотекама, без „PChar-Трикова“ без јасног контекста.

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

Праксно архитектонско решење је увођење малих адаптера/helper-а који тачно дефинишу како спољни подаци улазе и излазе. Примери:

  • CSV-Reader/-Writer: увек са TEncoding.UTF8 (или дефинисаном codepage) и јасним правилима сепаратора.
  • REST-Client/Server: JSON увек као UTF-8-бајтови, хедери исправно постављени, тело се не стримује „string-базирано“.
  • Windows-API-Wrapper: централне функције које Wide/Ansi чисто капсулирају.

Тиме се спречава да „одлуке о кодирању“ буду разбацане по кодној бази.

Typische Code-Fallen und wie man sie sauber behebt

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

У ANSI временима се Length(s) често злоупотребљавао као број бајтова. У UTF-16 то је погрешно. Кад вам требају бајт-низови, конвертујте експлицитно:

  • За UTF-8: TEncoding.UTF8.GetBytes(s)
  • За дефинисану ANSI-codepage: TEncoding.GetEncoding(1252).GetBytes(s) (само ако је стручно оправдано)

За величине бафера код API-позива важи: проверите да ли функција очекује јединице у знаковима или у бајтовима. Многе Wide-API-ји очекују број знакова, не бајтова. Документација и сигнатура одлучују, не интуиција.

PAnsiChar vs. PWideChar: DLL-Imports und externe Protokolle

Код DLL-Imports је велика опасност да сигнатуре у Delphi коду више не одговарају. Утврдите шта DLL очекује:

  • Очекује ли DLL UTF-8? Тада је uобичајено проследити PAnsiChar(UTF8String), али морате контролисати животни век и нул-терминацију.
  • Очекује ли UTF-16? Тада користите PWideChar и Wide-String-ове.

У сваком случају Imports требају бити капсулирани у посебну unit, да политика о string-овима не процури кроз цео пројекат.

Formatierung, Case-Umwandlung, Vergleich: Locale und Normalisierung

Unicode доноси и семантичке теме: велика/мала слова нису тривијална у свим језицима, а знакови могу имати различите нормалне форме. У типичним корпоративним апликацијама то је мање критично него у текст едиторима, али утиче на:

  • Сортирање и филтрирање (нпр. у grid-овима или претрагама),
  • Case-insensitive поређења за кључеве,
  • Генерисање имена фајлова или идентификатора.

Важно је имати јасно правило: шта су „кључеви“ (нпр. шифре артикала, шифре купаца) који треба да остану ASCII-блиски, а шта су „текстови“ који морају бити пуно Unicode-способни? Та подела смањује накнадне грешке.

GUI/Reporting: Fonts, Druck, PDF und Komponentenverhalten

VCL је од Unicode-верзија у основи Unicode-способан, али пракса зависи од компоненти и путева извода. Ризици се јављају код:

  • старијих report-engine-ова или PDF-генератора који претпостављају ANSI,
  • barcode/label штампе која захтева специфичне codepage-ове,
  • hardcodiranih font-ova или скупова знакова.

Планирајте ране тестове са реалним примерима података (именима, местима, специфичним знаковима, нелатиничним писмима кад је релевантно). Вредност није у „може Unicode“, већ у доказу: „Овај output је у нашем контексту коректан.“

Daten und Persistenz: Unicode endet nicht beim Code

Datenbank-Charsets und Collations sauber festlegen

Unicode миграција ће бити стабилна само ако су базе података и драјвери правилно конфигурисани. Примери:

  • Код PostgreSQL UTF-8 је обично стандард; ипак треба проверити client-encoding и понашање драјвера.
  • Код SQL Server разлика између VARCHAR и NVARCHAR је релевантна; погрешан избор колоне може изгубити знакове.
  • Код MariaDB/MySQL charset/collation (нпр. utf8mb4) су пресудни да 4-бајт знакови не буду одсечени.

У Delphi коду параметри и типови поља треба да буду коришћени тако да Unicode не буде „натеран“ да се назад конвертује. FireDAC овде обично пружа бољу контролу него веома стари слојеви приступа.

Legacy-Dateiformate: Migrationsregeln statt stiller Konvertierung

Ако ваша апликација годинама производи датотеке (формати експорта, архивски фајлови, власничке структуре), морате дефинисати:

  • Које постојеће датотеке остају „као што јесу“ и како ће се при читању исправно тумачити?
  • Који формати ће бити подигнути на UTF-8?
  • Постоје ли поља/заглавља за версионисање да би се нови и стари фајлови јасно разликовали?

Тиха конверзија без означавања је ризична јер се грешке често јаве касно. Боље: верзионисати, препознати и намерно мигрирати.

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

Unicode грешке су често зависне од података. Због тога „Happy Path“ тестови нису довољни. Потребан је скуп тестова који покрива проблематична места:

  • Roundtrip-Tests: Import → обрада → Export, а затим бајт-прецизна провера (за дефинисане формате).
  • DB-Roundtrip: писање/читање текстова са Umlaut-овима, акцентима и по потреби нелатиничним знаковима; провера једнакости.
  • Schnittstellen-Tests: REST-захтеви као UTF-8, хедери, JSON-escaping, логовање.
  • Regression: репродуковати старе податке и типичне корисничке сценарије, посебно претраге, филтере и сортирање.

За B2B системе је такође важно да грешке буду посматране: логовање не сме да уништи енкодинг. Ако се логови пишу као ANSI, у случају грешке губите информацију која је најпотребнија.

Planung und Aufwand: Was die Komplexität wirklich treibt

Обим рада на Unicode миграцији старих Delphi-пројеката зависи мање од „броја линија кода“, а више од спрегнутости и спољних зависности:

  • Много интеграција (DLL-ови, COM, уређаји, ERP/DMS/CRM) повећавају напор провере јер је кодирање релевантно на свакој граници.
  • Историјски формати (стари експорти, прилагођени CSV-еви) захтевају правила миграције и стратегије компатибилности.
  • Помењане Delphi-верзије или више производа из исте кодне базе повећавају координациони напор.
  • Стари слојеви приступа подацима (нпр. BDE) могу индиректно блокирати Unicode и указивати на потребу модернизације.

У пракси се показало ефикасним да се најпре стабилизује Unicode у језгру и у критичним токовима података. Након тога се модуле постепено доводе у ред. То смањује ризик и избегава дуге „Big Bang“ фазе без релиза.

Einordnung in Modernisierungspfade: REST, Services, Multiplattform

Unicode је често темељ када се стар софтвер модернизује. Типична следећа питања су:

  • REST-Server или REST-API: обезбедити да JSON/UTF-8 буду обрађени правилно.
  • Windows-Services или Linux-Services за стабилан рад (логовање, конфиг фајлови, протоколи).
  • Постепена модернизација UI у VCL-у, а касније евентуално мултиплатформски клијенти.

Редослед је важан: ако градите нове интерфејсе, правила о кодирању требају бити дефинисана пре тога. Unicode миграција „усput“ током развоја интерфејса иначе ствара тешко проверљиве грешке, јер се узрок и последица мешају.

За интерну повезаност у магазину прикладно је сместити суседне теме попут Delphi-модернизације, FireDAC-приступа подацима или архитектуре REST-Server-a као продубљујуће чланке, тако да читаоци могу циљано прећи на следећи технички корак.

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

Unicode миграција старих Delphi-пројеката није козметички upgrade, већ корекција основних претпоставки о тексту, бајтовима и интерфејсима. Ко приступи структуирано, добија више од „ Umlaut-и опет раде“: токови података постају недвосмислени, интеграције робусније, а каснија модернизација (нпр. REST-Server, сервиси, чишћење базе) је једноставнија јер кодирања више нису имплицитно „негде“.

Ako вам је за вашу Delphi-апликацију потребан конкретан план миграције, анализа ризика критичних тачака или подршка у имплементацији, најбржи следећи корак је технички уводни разговор о вашим оквирима и зависностима: Kontakt aufnehmen.

У стручној области Delphi Unicode Migration и Delphi Ansi Zu Unicode имају значајну улогу кад интеграције, токови података и даљи развој морају да се ускладе.

Projekt oder Modernisierungsvorhaben mit Net-Base besprechen.

Подели објаву

Поделите ову објаву директно

LinkedIn, X, XING, Facebook, WhatsApp и е-пошта су одмах доступни. За Instagram припремамо линк и кратак текст.

Е-пошта

Инстаграм се отвара у новој картици. Линк и кратак текст се претходно копирају у међуспремник.