Pointer<T>

Top  Previous  Next

Pretranslated C# code > Pointers > Pointer<T>

`Pointer<T>` represents Delphi typed pointers such as:

 

PInteger

PWord

PMyRecord

^TRecord

 

 

public struct Pointer<T> : IPointer<T>

 

 

Unlike `Pointer`, `Pointer<T>` is element-oriented. Pointer arithmetic and indexed access use elements of `T`.

 

Internally, `Pointer<T>` still uses the same shared byte-addressed backing model as all other pointer types. It does not have separate managed-array and raw-memory modes.

 

Array backing

 

Create a non-copying pointer view over a managed array:

 

int[] values = new int[10];

Pointer<int> p = new Pointer<int>(values, 0);

 

p.Assign(123);

p++;

p.Assign(456);

 

 

The writes update the original array.

 

A `DynamicArray<T>` can be used in the same way:

 

Pointer<int> p = new Pointer<int>(dynamicArray, index);

 

The pointer keeps a view of the current array backing. If `SetLength` later replaces the dynamic array backing, existing pointers continue to refer to the old backing, just as pointers into reallocated Delphi memory become stale.

 

Value constructor

 

Pointer<int> p = new Pointer<int>(value);

 

This creates a separate one-element backing containing a copy of `value`. It is not an alias to the original C# variable.

 

To represent Delphi `@LocalVariable`, generated code should use an addressable helper such as `DelphiCell<T>` rather than the value constructor.

 

Untyped and raw views

 

A typed pointer can be created from an existing untyped view:

 

Pointer<TRecord> typed =

    new Pointer<TRecord>(untyped);

 

This operation does not copy storage.

 

Convert back to an untyped or non-generic view with:

 

UntypedPointer bytes = typed.ToUntypedPointer();

Pointer raw = typed.ToPointer();

 

Dereferencing and indexing

 

 

T value = p.Deref();

p.Assign(value);

 

T fourth = p[3];

p[3] = value;

 

 

The index is relative to the current pointer and is expressed in elements of `T`.

 

Pointer arithmetic

 

p++;

p--;

p = p + 4;

p = p - 2;

 

For `Pointer<int>`, `p + 1` advances by one Delphi `Integer` element. For `Pointer<TRecord>`, it advances by one record according to `DelphiTypeLayout.SizeOf<TRecord>()`.

 

Length, capacity, and position

 

For `Pointer<T>`, helper properties are measured in elements of `T`:

 

`Length` is the number of complete elements remaining in the current view
`Capacity` is the known backing capacity expressed as elements
`Position` is the current element offset from the backing start

 

For unknown-length native backing, `Length` or `Capacity` may report `int.MaxValue`.

 

Native addresses

 

`ToIntPtr()` returns the address of the current element without converting the pointer into a different storage mode.

 

For managed byte-addressable array backing, the backing is pinned. Prefer scoped pinning for native calls:

 

using PointerPin pin = p.Pin();

NativeFunction(pin.Address);

 

`FromIntPtr()` is a compatibility helper that reads the current typed value. It does not restore or synchronize a separate buffer.

 

Raw layout restrictions

 

Exact typed access to a `T[]` backing is supported even when `T` contains managed references. Arbitrary raw-byte access is rejected for such element types.

 

For native storage or reinterpreted pointer casts, `T` must have a Delphi-compatible binary layout. Use `StructLayout` and `DelphiTypeLayout` registrations where required.

 

Legacy allocation constructor

 

The compatibility constructor:

 

new Pointer<T>(size, rawMemory)

 

has different meanings depending on `rawMemory`:

 

when `rawMemory` is `true`, `size` is a native byte count
when `rawMemory` is `false`, `size` is the managed element count

 

Generated code should prefer explicit `GetMem`, `AllocMem`, arrays, or dynamic arrays where possible, because those forms make the unit unambiguous.

 



This page belongs to the Delphi2C# Documentation

Delphi2C# home  Content