|
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:
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 |