Affix
view release on metacpan or search on metacpan
lib/Affix/Wrap.pod view on Meta::CPAN
=pod
=encoding utf-8
=head1 NAME
Affix::Wrap - Frictionless C/C++ Binding Generator for Affix
=head1 SYNOPSIS
use Affix::Wrap;
my $wrapper = Affix::Wrap->new(
project_files => ['/usr/include/sqlite3.h'],
include_dirs => ['/usr/include'],
types => {
'sqlite3' => 'Pointer[Void]' # Custom override
}
);
# Option 1: Instantly wrap and inject into the current namespace
# You may call functions exported by the lib immediately
$wrapper->wrap('libsqlite3.so', __PACKAGE__);
# Option 2: Generate a standalone Perl module file to disk
# This should get you started on a library wrapper you'll eventually put on CPAN
$wrapper->generate('libsqlite3.so', 'My::SQLite', 'lib/My/SQLite.pm');
=head1 DESCRIPTION
C<Affix::Wrap> is a frictionless binding generator that bridges C/C++ header files and L<Affix>. It parses headers to
extract functions, structs, enums, typedefs, macros, and global variables, automatically converting this information
into L<Affix> definitions.
It is designed to facilitate two primary developer workflows:
=over
=item 1. B<Rapid Prototyping (Runtime Wrapping)>
Parse headers on the fly and inject bindings directly into your running Perl environment via C<wrap()>. This is perfect
for private tooling, experimental scripts, or whenever you want to avoid the boilerplate of a dedicated FFI module.
=item 2. B<Distribution (Static Generation)>
Generate standalone F<.pm> files for CPAN via C<generate()>. This produces a pure-Perl module that depends only on
L<Affix>, ensuring fast load times and zero development dependencies (like C<Clang> or C<Affix::Wrap> itself) for your
end users.
=back
=head2 Parsing Drivers
C<Affix::Wrap> employs a dual-driver strategy:
=over
=item * B<Clang Driver (Recommended)>
The primary driver. It leverages C<clang -Xclang -ast-dump=json> to perform compiler-grade analysis of your headers. It
is highly accurate and handles complex C++ templates, macros, and deep inclusion chains with ease.
=item * B<Regex Driver (Fallback)>
A pure-Perl heuristic parser. While less capable than the Clang driver (it may struggle with complex macros or nested
C++ constructs), it requires no external dependencies and is sufficient for many straightforward C headers.
=back
=head1 Supported Features
C<Affix::Wrap> extracts and bridges:
=over
=item * Function signatures (including pointer-to-function arguments)
=item * Nested Structs and Unions
=item * Enums (maps them to Affix Dualvar Enums)
=item * Macros (numeric and string constants)
=item * Typedefs (follows deep typedef chains)
=item * Extern Global Variables (binds them via C<Affix::pin>)
lib/Affix/Wrap.pod view on Meta::CPAN
=item C<include_dirs>
Optional. An array reference of paths to search for C<#include "..."> directives. The directory of every file listed in
C<project_files> is automatically added to this list.
=item C<types>
Optional. A hash reference for manually mapping type names to L<Affix> type objects or definition strings. Very useful
for masking complex internal library structures behind Pointer[Void] handles.
=item C<driver>
Optional. Explicitly select the parser driver. Values are C<'Clang'> or C<'Regex'>. If omitted, C<Affix::Wrap> attempts
to find the C<clang> executable and falls back to Regex if unavailable.
=back
=head1 METHODS
=head2 wrap( $lib, [$target_package] )
$binder->wrap( $lib );
$binder->wrap( $lib, 'My::Package' );
Parses the project files and immediately binds all found entities (functions, variables, constants, types) to the
target package.
=over
=item C<$lib>
The shared library to link the functions against.
=item C<$target_package>
Optional. The namespace to inject symbols and types into. Defaults to the caller package.
=back
=head2 generate( $lib, $pkg, $output_file )
$binder->generate( 'mylib', 'My::Lib', 'lib/My/Lib.pm' );
Parses the headers and writes a fully functioning, standalone Perl .pm module to disk. This is highly recommended for
production modules to avoid the overhead of parsing headers at runtime.
=head2 parse( [$entry_point] )
my @nodes = $binder->parse;
Parses the project files and returns a list of Node objects (see B<Data Model> below). Use this if you want to inspect
the C header structure or generate code strings for a static Perl module.
The nodes are sorted by file name and line number to ensure deterministic output order.
=over
=item C<$entry_point>
Optional. The specific file to start parsing from. Defaults to the first file in C<project_files>.
=back
=head1 Data Model
The C<parse()> method returns a list of objects inheriting from C<Affix::Wrap::Entity>.
All nodes provide at least two key methods:
=over
=item * C<affix_type>: Returns a B<string> of Perl code representing the type or declaration (e.g., C<"Int">, C<"typedef Foo => Int">). Used for code generation.
=item * C<affix( $lib, $pkg )>: Performs the actual binding at runtime. Installs symbols into C<$pkg> using C<$lib>.
=back
=head2 Affix::Wrap::Type
Represents a generic C type (e.g., C<int>, C<void>, C<size_t>).
=head2 Affix::Wrap::Type::Pointer
Represents C<T*> types. Wraps another type object.
=head2 Affix::Wrap::Type::Array
Represents C<T[N]> fixed-size arrays. Wraps a type object and a count.
=head2 Affix::Wrap::Type::CodeRef
Represents function pointers (callbacks), e.g., C<void (*)(int)>.
=over
=item * C<ret>: Return type object.
=item * C<params>: ArrayRef of argument type objects.
=item * C<affix_type>: Returns string C<Callback[[Args] =E<gt> Ret]>.
=back
=head2 Affix::Wrap::Argument
Function arguments. Stringifies to "Type Name".
=head2 Affix::Wrap::Member
Struct/Union members.
=over
=item * C<definition>: If the member defines a nested struct/union inline, this holds that definition object.
=item * C<affix_type>: Returns the signature of the type OR the nested definition.
=back
=head2 Affix::Wrap::Function
( run in 0.702 second using v1.01-cache-2.11-cpan-f56aa216473 )