Ad Space — Top Banner

WideString Conversion Error

Delphi Programming Language

Severity: Moderate

What Does This Error Mean?

WideString conversion errors occur when Delphi cannot convert a string between ANSI (single-byte) and Unicode (wide/multi-byte) representations without data loss. This is most common in older Delphi code (pre-2009) upgraded to Delphi 2009 or later, where the default string type changed from AnsiString to UnicodeString. The fix is to identify where ANSI and Unicode strings are mixed and use the correct conversion functions.

Affected Models

  • Delphi 10.4 Sydney
  • Delphi 11 Alexandria
  • Delphi 12 Athens
  • Embarcadero RAD Studio
  • Free Pascal / Lazarus

Common Causes

  • Passing a UnicodeString to a function or DLL that expects an AnsiString (PAnsiChar)
  • Assigning a string containing non-ASCII characters to an AnsiString variable, losing those characters
  • Mixing AnsiString and WideString parameters when calling Windows API functions
  • Legacy code using Char (now WideChar) where PAnsiChar is expected by a DLL or COM function
  • Using string functions like Copy or Pos on WideString when the byte offsets differ from character offsets

How to Fix It

  1. Identify where the mismatch occurs. Common signs: string data is truncated, question marks appear in place of characters, or an explicit conversion exception fires. Run in the debugger and check string values at the conversion point.

    In Delphi 2009+, string is UnicodeString and Char is WideChar. Code written for earlier Delphi versions assumed Char = AnsiChar.

  2. Use explicit conversion functions instead of implicit assignment. To convert UnicodeString to AnsiString: AnsiStr := AnsiString(UnicodeStr). To convert the other way: UnicodeStr := String(AnsiStr).

    Implicit assignment between different string types compiles with a warning — treat these warnings as errors and fix them explicitly.

  3. For DLL calls that require PAnsiChar, use AnsiString as the intermediate: var A: AnsiString; A := AnsiString(MyString); DLLFunction(PAnsiChar(A));

    Never cast a UnicodeString pointer directly to PAnsiChar — the byte representation is different and will produce garbage or access violations.

  4. For Windows API calls, consistently use the W-suffixed (Unicode) versions: CreateFileW, GetWindowTextW, etc. Modern Delphi maps the unsuffixed names to the W versions automatically, but older code may have explicit A-suffixed calls that need updating.

    Check every Windows API call imported with external declarations for whether it uses A or W and whether it matches the string type being passed.

  5. Enable compiler warnings for implicit string conversion: {$WARN IMPLICIT_STRING_CAST ON} {$WARN IMPLICIT_STRING_CAST_LOSS ON}. Fix every warning — each one is a potential character loss.

    String cast loss warnings flag exactly the places where non-ASCII characters would be silently dropped.

When to Call a Professional

String conversion issues in migrated Delphi code can be subtle — some characters convert fine while others are lost. Search the codebase for AnsiString, PAnsiChar, and WideString declarations and review each one. For Windows API calls, use the W (wide) versions of functions and pass PWideChar, or use the A (ANSI) versions and pass PAnsiChar — do not mix them.

Frequently Asked Questions

Why did Delphi change the default string type in version 2009?

Delphi 2009 introduced full Unicode support, changing the default string type from AnsiString (1 byte per character) to UnicodeString (2 bytes per character). This was a breaking change for existing code but necessary for proper internationalization support. Code written before 2009 that is compiled with modern Delphi versions will often produce implicit conversion warnings that need to be addressed.

How do I know if my string contains characters that will be lost in ANSI conversion?

Use SysUtils.WideCharToStrVar or check manually: if there are any characters with codepoint above 127 in the string, they may not have an ANSI representation in the current Windows code page. The function AnsiStrings.AnsiToUtf8 and back is a safe round-trip test — if the result differs from the original, some characters would be lost.

Is WideString the same as UnicodeString in modern Delphi?

They are both 2 bytes per character but they are different types. WideString is a COM BSTR-compatible type allocated by the Windows memory manager. UnicodeString is Delphi's native string type with reference counting, allocated by Delphi's own memory manager. For most Delphi code use UnicodeString (the default string). Use WideString only when COM interop requires it.