The fastest way to use Affix::Wrap is Runtime Wrapping. In this workflow, you parse the headers and bind the functions immediately when your script starts. This is ideal for rapid prototyping, internal scripts, or testing, as you don't need to generate a separate .pm file.

The Recipe

In this demo, we'll use Affix::Build to build a library and Affix::Wrap to wrap it instantly.

use v5.40;
no warnings 'once';
use Affix qw[:all];
use Affix::Build;
use Affix::Wrap;
use Path::Tiny;

# 1. Setup the C Project
my $dir = Path::Tiny->tempdir( CLEANUP => 0 );
my $src = $dir->child('physics.c');
my $hdr = $dir->child('physics.h');

# A header with documentation
$hdr->spew_utf8(<<~'H');
    typedef struct { double x, y, z; } Vector3;

    /**
     * Adds two vectors.
     */
    Vector3 vec_add(Vector3 a, Vector3 b);

    // Global gravity constant
    extern double GRAVITY;
    H

# Implementation
$src->spew_utf8(<<~'C');
    #include "physics.h"
    #ifdef _WIN32
    __declspec(dllexport)
    #endif
    double GRAVITY = 9.81;

    #ifdef _WIN32
    __declspec(dllexport)
    #endif
    Vector3 vec_add(Vector3 a, Vector3 b) {
        Vector3 r = { a.x + b.x, a.y + b.y, a.z + b.z };
        return r;
    }
    C

# 2. Compile the library
my $compiler = Affix::Build->new( build_dir => $dir );
$compiler->add($src);
my $lib_path = $compiler->link;

# 3. The Magic: Bind it!
Affix::Wrap->new( project_files => [$hdr], include_dirs => [$dir] )->wrap($lib_path);

# 4. Use it
# The functions and typedefs are now installed in our package!
say "Gravity is: $main::GRAVITY";
my $v1 = { x => 1, y => 2, z => 3 };
my $v2 = { x => 4, y => 5, z => 6 };

# Affix::Wrap automatically handled the Struct definition for Vector3
my $v3 = vec_add( $v1, $v2 );
say "Result: $v3->{x}, $v3->{y}, $v3->{z}";

Output:

Gravity is: 9.81
Result: 5, 7, 9

How It Works

Note that we didn't write a single Struct[...] or affix signature manually.

Kitchen Reminders