Affix

 view release on metacpan or  search on metacpan

README.md  view on Meta::CPAN

}
```

### `is_pin( $var )`

Returns true if the variable is currently bound to C memory via `pin`, `cast`, or pointer dereferencing. Returns
false for ordinary Perl scalars.

```perl
my $x = 42;
say is_pin($x); # false

pin $x, libc(), 'errno', Int;
say is_pin($x); # true
```

## Lifecycle & Ownership

### `attach_destructor( $pin, $func_ptr, [$lib] )`

Attaches a custom C function to be called when the Pin is destroyed. This is incredibly useful for C libraries that
require specific cleanup routines (e.g., `SDL_DestroyWindow`, `sqlite3_free`).

```perl
# Find the address of the library's custom free function
my $free_func = find_symbol($my_lib, 'custom_free');

# When $ptr goes out of scope, Affix will call custom_free($ptr)
attach_destructor($ptr, $free_func, $my_lib);
```

### `readonly( $pin, [$bool] )`

Gets or sets the "const" status of a memory pin. If set to true, any attempt to write to that memory from Perl will
throw an exception.

```
readonly($point, 1);
$point->{x} = 20; # CRASH: Modification of a read-only C value
```

## Type Casting

### `cast( $ptr, $type )`

The most powerful tool in the memory kit. It "overlays" a C type definition onto a raw memory address.

```perl
my $mem = malloc(16);
my $point = cast($mem, Struct[ x => Int, y => Int ]);
$point->{x} = 10;
```

# POINTER UTILITIES

Navigate and inspect raw pointers with helper functions for address arithmetic, null checks, and more.

### `address( $ptr )`

Returns the virtual memory address of the pointer as a Perl Unsigned Integer (`UInt64`). Useful for passing addresses
to other FFI libraries or debugging.

```
say sprintf("Address: 0x%X", address($ptr));
```

### `ptr_add( $ptr, $offset_bytes )`

Returns a new **unmanaged alias Pin** offset by `$offset_bytes`.

```perl
my $int_arr   = calloc(10, Int);
my $next_elem = ptr_add($int_arr, sizeof(Int));
```

_Note: If `$ptr` is an Array type, `ptr_add` correctly decays the returned pin into a Pointer to the element type._

### `ptr_diff( $ptr1, $ptr2 )`

Returns the byte difference (`$ptr1 - $ptr2`) between two pointers as an integer.

### `is_null( $ptr )`

Returns true if the address is `NULL` (`0x0`).

### `strnlen( $ptr, $max )`

Safe string length calculation. Checks the pointer for a `NULL` terminator, scanning at most `$max` bytes.

### `raw( $ptr, $length_in_bytes )`

Returns a Perl string containing the raw, un-decoded binary data extracted directly from the memory address. This is
the programmatic, binary equivalent of `dump()`.

### `snapshot( $pin )`

Deeply reads the C memory backing a Pin and returns a pure, non-magical native Perl data structure (ArrayRef, HashRef,
or Scalar). Because it does not apply VTable magic to the returned values, reading elements from the returned structure
in a bulk operation (like summing a 10,000 element array) is exceptionally fast.

# Raw Memory Operations

Classic C memory functions (memcpy, memset, etc.) available directly from Perl for high-performance byte manipulation.
These functions accept either Pins or raw integer addresses.

- `memcpy( $dest, $src, $bytes )`: Copies exactly `$bytes` from `$src` to `$dest`.
- `memmove( $dest, $src, $bytes )`: Copies `$bytes` from `$src` to `$dest`. Safe to use if the memory regions overlap.
- `memset( $ptr, $byte_val, $bytes )`: Fills the first `$bytes` of the memory block with the value `$byte_val`.
- `memcmp( $ptr1, $ptr2, $bytes )`: Compares the first `$bytes` of two memory blocks. Returns an integer less than, equal to, or greater than zero.
- `memchr( $ptr, $byte_val, $bytes )`: Locates the first occurrence of `$byte_val` within the first `$bytes` of the memory block. Returns a new Pin pointing to the match, or `undef`.

# `Const` & Readonly Memory

Enforce C's const contract at the Perl level. Affix intercepts writes to read-only memory and throws a fatal exception:
`Modification of a read-only C value attempted`.

## Declarative Const: `Const[ $type ]`

You can wrap any type in `Const[ ... ]` within a signature.

```perl



( run in 0.875 second using v1.01-cache-2.11-cpan-f9ab5d97e31 )