Affix

 view release on metacpan or  search on metacpan

lib/Affix.pod  view on Meta::CPAN


    # 2. Read the memory immediately as an integer value
    my $val = cast($void_ptr, Int); # Returns 99

=head1 POINTER UTILITIES

=head3 C<address( $ptr )>

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

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

=head3 C<ptr_add( $ptr, $offset_bytes )>

Returns a new B<unmanaged alias Pin> offset by C<$offset_bytes>.

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

I<Note: If C<$ptr> is an Array type, C<ptr_add> correctly decays the returned pin into a Pointer to the element type.>

=head3 C<ptr_diff( $ptr1, $ptr2 )>

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

=head3 C<is_null( $ptr )>

Returns true if the address is C<NULL> (C<0x0>).

=head3 C<strnlen( $ptr, $max )>

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

=head1 RAW MEMORY OPERATIONS

Affix exposes standard C memory operations for high-performance, raw byte manipulation. These functions accept either
Pins or raw integer addresses.

=over

=item * C<memcpy( $dest, $src, $bytes )>: Copies exactly C<$bytes> from C<$src> to C<$dest>.

=item * C<memmove( $dest, $src, $bytes )>: Copies C<$bytes> from C<$src> to C<$dest>. Safe to use if the memory regions overlap.

=item * C<memset( $ptr, $byte_val, $bytes )>: Fills the first C<$bytes> of the memory block with the value C<$byte_val>.

=item * C<memcmp( $ptr1, $ptr2, $bytes )>: Compares the first C<$bytes> of two memory blocks. Returns an integer less than, equal to, or greater than zero.

=item * C<memchr( $ptr, $byte_val, $bytes )>: Locates the first occurrence of C<$byte_val> within the first C<$bytes> of the memory block. Returns a new Pin pointing to the match, or C<undef>.

=back

=head1 LIBRARIES & SYMBOLS

Loading dynamic libraries across different operating systems (Windows, macOS, Linux, BSD) can be a nightmare of varying
extensions, prefixes, and search paths. Affix abstracts this complexity away with a smart library discovery engine.

=head2 Library Discovery

When you provide a bare library name (e.g., C<'z'>, C<'ssl'>, C<'user32'>) rather than an absolute path, Affix
automatically formats the name for the current platform (e.g., C<libz.so>, C<libz.dylib>, C<z.dll>) and searches the
following locations in order:

=over

=item 1. B<Standard System Paths:> Windows C<System32>/C<SysWOW64>; Unix C</usr/local/lib>, C</usr/lib>, C</lib>, C</usr/lib/system>.

=item 2. B<Environment Variables:> Paths defined in C<LD_LIBRARY_PATH>, C<DYLD_LIBRARY_PATH>, C<DYLD_FALLBACK_LIBRARY_PATH>, or C<PATH>.

=item 3. B<Local Paths:> The current working directory (C<.>) and its C<lib/> subdirectory.

=back

=head2 Functions

=head3 C<load_library( $path_or_name )>

Locates and loads a dynamic library into memory, returning an opaque C<Affix::Lib> handle.

    my $lib = load_library('sqlite3');

B<Lifecycle:> Library handles are thread-safe and internally reference-counted. The underlying OS library is only
closed (e.g., via C<dlclose> or C<FreeLibrary>) when all Affix wrappers and pins relying on it are destroyed.

I<Note:> When using C<affix()> or C<wrap()>, you can safely pass the string name directly (e.g., C<affix('sqlite3',
...)>) and Affix will call C<load_library> for you internally. If you pass C<undef> instead of a library name, Affix
will search the currently running executable process.

=head3 C<locate_lib( $name, [$version] )>

Searches for a library using Affix's discovery engine and returns its absolute file path as a string. It B<does not>
load the library into memory. This is useful if you need to pass the library path to another tool or check for its
existence.

    # Find libssl.so.1.1 or libssl.1.1.dylib
    my $path = locate_lib('ssl', '1.1');
    say "Found SSL at: $path" if $path;

=head3 C<find_symbol( $lib_handle, $symbol_name )>

Looks up an exported symbol (function or global variable) inside an already-loaded C<Affix::Lib> handle. Returns an
unmanaged C<Affix::Pointer> (Pin) of type C<Pointer[Void]> pointing to the memory address of the symbol.

    my $lib = load_library('m');

    # Get the raw memory address of the 'pow' function
    my $pow_ptr = find_symbol($lib, 'pow');

    if ($pow_ptr) {
        say sprintf("pow() is located at: 0x%X", address($pow_ptr));
    }

Returns C<undef> if the symbol cannot be found.

=head3 C<libc()> and C<libm()>

Helper functions that locate and return the file paths to the standard C library and the standard math library for the
current platform. Because platform implementations differ wildly (e.g., MSVCRT on Windows, glibc on Linux, libSystem on
macOS), using these helpers guarantees you get the correct library.

    # Bind 'puts' from the standard C library
    affix libc(), 'puts', [String] => Int;

    # Bind 'cos' from the math library
    affix libm(), 'cos', [Double] => Double;

=head3 C<get_last_error_message()>

If C<load_library>, C<find_symbol>, or a signature parsing step fails, this function returns a string describing the
most recent internal or operating system error (via C<dlerror> or C<FormatMessage>).

    my $lib = load_library('does_not_exist');
    if (!$lib) {
        die "Failed to load library: " . get_last_error_message();
    }

=head1 INTROSPECTION

When working with C APIs, you often need to know exactly how much memory a structure consumes or where a specific field
is located within a block of memory. Affix provides compiler-grade type introspection.

=head3 C<sizeof( $type )>

Returns the size, in bytes, of any Affix Type object or registered C<typedef> name.

    # C: sizeof(int);
    say sizeof( Int ); # 4 (usually)

    # C: sizeof(Point);
    say sizeof( Point() ); # 8

=head3 C<alignof( $type )>

Returns the alignment boundary (in bytes) required by the C ABI for the given type.

    say alignof( Int64 ); # 8 (usually)



( run in 0.993 second using v1.01-cache-2.11-cpan-acf6aa7dc9e )