Affix

 view release on metacpan or  search on metacpan

lib/Affix.pod  view on Meta::CPAN

=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

Query type sizes, alignments, and field offsets like a compiler would. 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.

=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)

    # Struct alignment is dictated by its largest member
    typedef Mixed => Struct[ a => Char, b => Double ];
    say alignof( Mixed() ); # 8

=head3 C<offsetof( $struct_or_union, $field_name )>

Returns the byte offset of a named field within an Aggregate type (Struct or Union). This is incredibly useful for
manual pointer arithmetic.

    typedef Rect => Struct[ x => Int, y => Int, w => Int, h => Int ];

    # C: offsetof(Rect, w);
    say offsetof( Rect(), 'w' ); # 8 (skips x and y, 4 bytes each)

=head3 C<types()>

Returns a list of all custom type names currently registered in Affix's global type registry via C<typedef>. In scalar
context, returns the total number of registered types.

    my @known_types = types();
    say "Registered types: " . join(', ', @known_types);

=head1 INTERFACING WITH OTHER LANGUAGES

Guidelines for calling into C++, Rust, Fortran, Go, and Assembly from Affix. Because Affix dynamically loads symbols
according to the C ABI, it can interact with libraries written in almost any language, provided they expose their
functions correctly. Companion modules like L<Affix::Build> make compiling these languages seamless.

Here are the requirements and quirks for interfacing with non-C languages.

=head2 C++

C++ uses "name mangling" to support function overloading and namespaces, which alters the final symbol name inside the
compiled library.



( run in 1.605 second using v1.01-cache-2.11-cpan-6736b670a1e )