Sometimes you don't want to call a C function; you just want to use C's knowledge of memory layout. If you are parsing a binary file format or a network protocol defined in a C header, you could manually calculate offsets and padding, but that is a recipe for "off-by-one" disasters.

Affix allows you to use its internal JIT compiler to perform runtime introspection on types, giving you the exact sizeof and offsetof values for the current CPU architecture.

The Recipe

We will define a complex, padded C struct and use Affix to write a "pure Perl" binary parser that respects C's alignment rules.

use v5.40;
use Affix qw[:all];

# 1. Define the structure in the global registry
typedef Header => Struct [
    magic   => Array [ Char, 4 ],
    version => UInt16,
    _pad    => UInt16,              # Manual padding is often needed in binary formats
    flags   => UInt32,
    offset  => UInt64
];

# 2. Introspect the layout
my $size  = sizeof Header();
my $v_off = offsetof Header(), 'version';
my $f_off = offsetof Header(), 'flags';
say "Total Struct Size: $size bytes";
say 'Version field starts at byte: ' . $v_off;
say 'Flags field starts at byte:   ' . $f_off;

# 3. Use this info to parse raw data (e.g. from a file)
# Build a 24-byte buffer that matches the aligned layout.
# Note: the UInt64 'offset' field is aligned to an 8-byte boundary, so it
# actually starts at byte 16 (not byte 12) even though the preceding fields
# only take up 12 bytes.
my $raw_data = pack 'a4vvVx4Q', 'AFFX', 1, 0, 0xFF, 0x1234;

# Copy the raw bytes into a heap buffer, then plate the struct over it
my $buf = calloc 1, sizeof Header();
memcpy $buf, $raw_data, length $raw_data;
my $header = cast $buf, Header();
if ( $header->{magic} eq 'AFFX' ) {
    say 'Valid header found!';
    say sprintf 'Flags:  0x%X', $header->{flags};
    say sprintf 'Offset: 0x%X', $header->{offset};
}

The output looks like this:

Total Struct Size: 24 bytes
Version field starts at byte: 4
Flags field starts at byte:   8
Valid header found!
Flags:  0xFF
Offset: 0x1234

How It Works

Kitchen Reminders