PAnsiChar

Top  Previous  Next

Pretranslated C# code > Pointers > PAnsiChar

Delphi2C# converts the Delphi PAnsiChar type to System.PAnsiChar.

 

PAnsiChar is a typed pointer to ANSI character bytes. It remains distinct from PChar, which points to UTF-16 characters.

 

The separate runtime type allows generated C# code to preserve byte addressing, null termination, ANSI code pages, pointer arithmetic, writable buffers, and byte-exact RTL operations.

 

The generated code normally imports the required runtime declarations with:

 

    using System;

    using static System.SystemInterface;

    using static System.Sysutils.SysutilsInterface;

 

Type mapping

 

The related Delphi types are mapped as follows:

 

   Delphi PAnsiChar     -> C# PAnsiChar

   Delphi AnsiChar      -> C# byte

   Delphi AnsiString    -> C# AnsiString

   Delphi PChar         -> C# PChar

   Delphi Pointer       -> C# Pointer

 

A Delphi PAnsiChar variable is initialized with the default null pointer value:

 

Delphi:

 

    var

      P: PAnsiChar;

 

C#:

 

    PAnsiChar P = default;

 

System.PAnsiChar is a value type that wraps Pointer<byte> and carries the ANSI code page associated with the addressed bytes.

 

 

Dereferencing and indexing

 

Dereferencing a Delphi PAnsiChar produces AnsiChar, which Delphi2C# represents as byte.

 

Delphi:

 

    C := P^;

 

C#:

 

    C = P.Deref();

 

Writing through the pointer becomes a byte assignment through the PAnsiChar API:

 

Delphi:

 

    P^ := 'A';

 

C#:

 

    P.Assign((byte)'A');

 

Typed-pointer indexing is already zero-based in Delphi, so Delphi2C# keeps the index unchanged:

 

Delphi:

 

    C := P[2];

    P[2] := 'X';

 

C#:

 

    C = P[2];

    P[2] = (byte)'X';

 

Each index addresses one byte. It does not address one decoded Unicode character and does not skip a complete multibyte character.

 

Null pointers

 

Delphi nil is represented by default PAnsiChar:

 

Delphi:

 

    P := nil;

 

C#:

 

    P = default;

 

The runtime exposes IsNull and SetNull for typed null-pointer handling:

 

    bool isNull = P.IsNull();

    P.SetNull();

 

Dereferencing or writing through a null PAnsiChar raises a managed pointer exception instead of accessing address zero.

 

 

Null termination and buffer length

 

PAnsiChar follows null-terminated ANSI string conventions. The Length property scans bytes from the current pointer position up to the first zero byte or the end of the available backing storage.

 

The Capacity property reports the number of bytes available from the current pointer position. Capacity includes space that may contain the terminating zero and additional writable buffer bytes.

 

The RTL StrLen overload returns the number of bytes before the first zero:

 

Delphi:

 

    L := StrLen(P);

 

C#:

 

    L = StrLen(P);

 

Embedded zero bytes terminate PAnsiChar text operations even though the same zero bytes remain valid data inside an AnsiString with an explicit Length.

 

 

Conversion from AnsiString

 

An explicit Delphi cast from AnsiString to PAnsiChar becomes an explicit C# cast:

 

Delphi:

 

    P := PAnsiChar(S);

 

C#:

 

    P = (PAnsiChar)S;

 

For a non-empty AnsiString, the managed cast creates null-terminated byte storage carrying the AnsiString code page. For an empty AnsiString, it returns a null PAnsiChar, matching the nil data pointer used by an empty Delphi long string.

 

The managed runtime copies AnsiString bytes into pointer storage because System.AnsiString is immutable and CLR object storage cannot be exposed as a permanently writable Delphi string buffer.

 

When generated code needs a writable pointer and a later AnsiString result, it uses PAnsiChar.Synchronize or AnsiStringBuffer.Commit to copy the modified bytes back to the AnsiString variable.

 

 

Conversion from ShortString

 

An explicit Delphi cast from ShortString also produces PAnsiChar:

 

    P = (PAnsiChar)shortValue;

 

ShortString has inline-style storage semantics, so an empty ShortString produces a non-null buffer containing a zero terminator. This differs from the null pointer produced by an empty AnsiString cast.

 

 

Conversion from Unicode string

 

 

When the Delphi source converts Unicode String text to PAnsiChar, Delphi2C# constructs an ANSI pointer buffer through the selected code page:

 

    P = new PAnsiChar(unicodeText);

 

The constructor converts the UTF-16 text to AnsiString bytes with AnsiStringSettings.DefaultCodePage unless a concrete code page is supplied by the generated context.

 

This is a character encoding boundary. It differs from Move, which copies raw memory bytes without encoding.

 

 

Writable pointer buffers

 

The PAnsiChar constructors create writable byte storage for translated calls that receive an output buffer:

 

    PAnsiChar buffer = new PAnsiChar(size, alloc: true);

 

A constructor from AnsiString, ShortString, string, byte[], or AnsiChar creates or wraps suitable byte storage and records its code page.

 

Assign(AnsiString), Assign(ShortString), and Assign(string) write the converted bytes followed by a zero terminator. The destination capacity is checked, and pointer writes never resize the existing backing storage.

 

The PAnsiChar Insert method shifts bytes within the existing buffer and also requires enough capacity for the inserted bytes and terminator.

 

 

AnsiStringBuffer

 

Delphi2C# uses AnsiStringBuffer when a Delphi operation writes through a pointer into storage that must later become an immutable AnsiString value.

 

    AnsiString value = "ABCDE";

    using AnsiStringBuffer buffer = new AnsiStringBuffer(value, capacity: 16);

    PAnsiChar P = buffer.Pointer;

    P[0] = (byte)'a';

    value = buffer.Commit();

 

Commit() reads bytes up to the first zero terminator. Commit(length) copies the specified number of bytes and therefore preserves embedded zero bytes.

 

PAnsiChar.Synchronize provides the corresponding copy-back operation for an existing pointer:

 

    P.Synchronize(ref value);

 

Synchronization to AnsiString or ShortString reads up to the first zero terminator. Synchronization to byte[] copies the same null-terminated data bytes without performing text encoding.

 

 

Pointer arithmetic

 

PAnsiChar arithmetic is measured in bytes because the pointed Delphi element type is AnsiChar.

 

Delphi:

 

    Inc(P);

    Dec(P);

 

C#:

 

    ++P;

    --P;

 

Addition and subtraction also move by byte offsets:

 

    PAnsiChar next = P + 4;

    PAnsiChar previous = P - 1;

 

The resulting pointer retains the code page and shares the original backing storage. Its Length and Capacity are calculated from the new pointer position.

 

Pointer subtraction in Delphi source is translated through the pointer position or address support when an integer byte distance is required.

 

 

Addressing AnsiString elements

 

The typed Addr overload for AnsiString returns PAnsiChar. Delphi2C# first translates the one-based AnsiString element index to a zero-based byte index:

 

Delphi:

 

    P := Addr(S[2]);

 

C#:

 

    P = Addr(S, 2 - 1);

 

The resulting pointer starts at the requested byte position and carries the AnsiString code page.

 

 

Conversion back to AnsiString

 

A Delphi conversion from PAnsiChar to AnsiString becomes an explicit typed conversion or a call to ToAnsiString:

 

    AnsiString value1 = (AnsiString)P;

    AnsiString value2 = P.ToAnsiString();

 

The conversion reads bytes up to the first zero terminator and preserves the PAnsiChar code page.

 

When the Delphi operation supplies an explicit length, Delphi2C# binds SetString to the PAnsiChar overload instead. This preserves embedded zero bytes and does not stop at the first terminator:

 

    SetString(ref value, P, length);

 

ToString decodes the null-terminated bytes to C# UTF-16 text. This is an explicit ANSI-to-Unicode boundary and is not used for byte-preserving pointer operations.

 

 

Move operations

 

Delphi2C# binds Move calls involving PAnsiChar to byte-oriented overloads. Source offsets, destination offsets, and count values are byte based.

 

    Move(source, sourceOffset, ref destination, destinationOffset, count);

 

The runtime supports PAnsiChar-to-PAnsiChar, PAnsiChar-to-AnsiString, and AnsiString-to-PAnsiChar copies. These overloads copy bytes exactly and do not invoke a character encoding.

 

Overlapping pointer moves use temporary storage where required to reproduce Delphi Move semantics.

 

The destination pointer or AnsiString must already provide enough storage. A Move call never enlarges a PAnsiChar buffer.

 

 

Memory allocation and release

 

Delphi GetMem and FreeMem calls bind to PAnsiChar overloads when the destination has static type PAnsiChar:

 

Delphi:

 

    GetMem(P, Size);

    FreeMem(P);

 

C#:

 

    GetMem(ref P, Size);

    FreeMem(ref P);

 

GetMem allocates the requested number of bytes. FreeMem releases the pointer backing when applicable and replaces the ref pointer variable with default.

 

The SysUtils StrNew function allocates a null-terminated copy of another PAnsiChar, and StrDispose releases that pointer backing:

 

    PAnsiChar copy = StrNew(source);

    StrDispose(copy);

 

StrBufSize returns the available buffer capacity, while StrLen returns the number of bytes before the terminator.

 

 

SysUtils pointer functions

 

Delphi2C# provides PAnsiChar overloads for the ANSI pointer functions declared by System.SysUtils.

 

The byte-oriented family includes StrLen, StrEnd, StrMove, StrCopy, StrECopy, StrLCopy, StrCat, StrLCat, StrComp, StrIComp, StrLComp, StrLIComp, StrScan, StrRScan, StrPos, TextPos, StrUpper, and StrLower.

 

The AnsiStrComp, AnsiStrIComp, AnsiStrLComp, AnsiStrLIComp, AnsiStrLower, AnsiStrUpper, AnsiStrLastChar, AnsiStrPos, AnsiStrScan, and AnsiStrRScan overloads retain code-page-aware or multibyte-aware behavior where the Delphi routine requires it.

 

StrByteType, StrCharLength, and StrNextChar use the PAnsiChar code page to distinguish single-byte data, lead bytes, and trail bytes and to advance across a complete encoded character.

 

Formatting overloads such as StrFmt and StrLFmt accept PAnsiChar format and destination buffers. They format through the ANSI RTL path and write null-terminated bytes in the destination code page.

 

 

Pointer conversions

 

PAnsiChar remains typed during Delphi overload resolution. Delphi2C# does not implicitly replace it with PChar or Pointer<byte> merely because a C# conversion is available.

 

When the selected Delphi target type is Pointer, the generated C# conversion is explicit:

 

    Pointer rawPointer = (Pointer)P;

 

When a Pointer<byte> view is required, the runtime exposes AsPointer:

 

    Pointer<byte> bytePointer = P.AsPointer();

 

When an UntypedPointer view is required, the runtime exposes ToUntypedPointer and an implicit conversion:

 

    UntypedPointer rawView = P.ToUntypedPointer();

 

Conversions from Pointer<byte>, Pointer, and UntypedPointer to PAnsiChar retain byte-pointer behavior and attach the selected or default ANSI code page.

 

 

Pointer comparison

 

The PAnsiChar == and != operators compare pointer identity and position. They do not compare the null-terminated byte strings addressed by the pointers.

 

Delphi string comparisons between PAnsiChar values are bound to StrComp, AnsiStrComp, or another matching RTL function when content comparison is required.

 

 

TVarRec and array of const

 

A statically typed Delphi PAnsiChar expression creates a TVarRec with VType vtPChar:

 

    TVarRec argument = TVarRec.FromPAnsiChar(P);

 

The runtime reads the typed value with ToPAnsiCharValue:

 

    PAnsiChar value = argument.ToPAnsiCharValue();

 

PAnsiChar remains distinct from PChar in array of const. PAnsiChar uses vtPChar, while PChar uses vtPWideChar.

 

Dereferencing the pointer before creating the TVarRec changes the static value type from PAnsiChar to AnsiChar, so the generated TVarRec then uses vtChar and stores a byte.

 

 

Translation summary

 

Delphi2C# applies the following PAnsiChar translation rules:

 

Delphi PAnsiChar becomes System.PAnsiChar.
Delphi AnsiChar becomes byte.
A PAnsiChar variable is initialized with default.
Delphi nil becomes default.
P^ reads become P.Deref().
P^ writes become P.Assign(byte).
Typed-pointer indexes remain zero-based byte indexes.
Pointer arithmetic advances in bytes.
An explicit AnsiString cast becomes (PAnsiChar)value.
An empty AnsiString cast produces a null pointer.
PAnsiChar remains distinct from PChar, Pointer<byte>, and Pointer.
Null-terminated conversions stop at the first zero byte.
SetString with an explicit length preserves embedded zero bytes.
Move copies raw bytes without encoding.
GetMem, FreeMem, StrNew, and StrDispose bind to PAnsiChar overloads.
A PAnsiChar array of const value uses vtPChar.
Writable pointer changes are copied back explicitly when the destination is an immutable AnsiString.

 

These transformations reproduce Delphi ANSI character pointer semantics without converting the addressed bytes to UTF-16 text during pointer operations.

 

 

 



This page belongs to the Delphi2C# Documentation

Delphi2C# home  Content