Affix

 view release on metacpan or  search on metacpan

t/007_pointers.t  view on Meta::CPAN


    # Assigning directly ($p_val = 0) would overwrite the magic scalar with a normal SV*
    $$p_val = 0;

    # Layer 2: Pointer to Layer 1 (int**)
    my $pp_mem = malloc(8);
    my $pp_val = Affix::cast( $pp_mem, Pointer [ Pointer [Int] ] );
    $$pp_val = $p_val;    # Writes address of $p_mem into $pp_mem

    # Layer 3: Pointer to Layer 2 (int***)
    my $ppp_mem = malloc(8);
    my $ppp_val = Affix::cast( $ppp_mem, Pointer [ Pointer [ Pointer [Int] ] ] );

    # Dereference to invoke SET magic, writing the pointer address to memory.
    $$ppp_val = $pp_val;

    # Call Function
    $set_deep->( $ppp_val, 12345 );

    # Verification
    is $$p_val, 12345, '***int deep write successful via Pins';

    # Cleanup (Freeing the originals clears the memory)
    Affix::free($p_mem);
    Affix::free($pp_mem);
    Affix::free($ppp_mem);

    # Manual Memory Management (malloc/free/cast)
    isa_ok my $get_heap = wrap( $lib_path, 'get_heap_int', [Int] => Pointer [Int] ), ['Affix'];

    # Alias libc free to avoid conflict with Affix::free
    diag affix( $lib_path, 'libc_free', [ Pointer [Void] ] => Void );
    my $heap_ptr = $get_heap->(99);
    ok $heap_ptr, 'Received pointer from C';
    is $$heap_ptr, 99, 'Dereferenced managed pointer value';
    $$heap_ptr = 88;
    is $$heap_ptr, 88, 'Modified heap memory via magic deref';
    my $void_alias = Affix::cast( $heap_ptr, Pointer [Void] );
    my $addr       = $$void_alias;
    ok $addr > 0, 'Cast to void*, deref returns address';
    my $int_alias = Affix::cast( $void_alias, Pointer [Int] );
    is $$int_alias, 88, 'Cast back to int*, value preserved';

    # Use the bound C free
    libc_free($heap_ptr);
    pass 'Freed C memory';
};
subtest 'Custom Destructors' => sub {

    # Get library object for libc
    my $libc       = load_library( libc() );
    my $malloc_ptr = find_symbol( $libc, 'malloc' );
    my $free_ptr   = find_symbol( $libc, 'free' );
    {
        # Allocate memory using libc's malloc, not Affix's managed malloc
        my $malloc = wrap( undef, $malloc_ptr, [Size_t] => Pointer [Void] );
        my $p      = $malloc->(16);

        # Attaching free() as a destructor.
        # When $p goes out of scope, Affix will call free($p).
        attach_destructor( $p, $free_ptr, $libc );
    }
    pass 'Pin with custom destructor went out of scope without crashing';
};
#
done_testing;



( run in 0.504 second using v1.01-cache-2.11-cpan-e1769b4cff6 )