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