Affix

 view release on metacpan or  search on metacpan

README.md  view on Meta::CPAN

my $lib = load_library('sqlite3');
```

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

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

### `locate_lib( $name, [$version] )`

Searches for a library using Affix's discovery engine and returns its absolute file path as a string. It **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.

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

### `find_symbol( $lib_handle, $symbol_name )`

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

```perl
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 `undef` if the symbol cannot be found.

### `libc()` and `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.

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

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

### `get_last_error_message()`

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

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

# 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.

### `sizeof( $type )`

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

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

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

### `alignof( $type )`

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

```perl
say alignof( Int64 ); # 8 (usually)

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

### `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.

```perl
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)
```

### `types()`

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

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

# INTERFACING WITH OTHER LANGUAGES

Because Affix dynamically loads symbols according to the C Application Binary Interface (C ABI), it can interact with
libraries written in almost any language, provided they expose their functions correctly. Companion modules like



( run in 1.644 second using v1.01-cache-2.11-cpan-40ba7b3775d )