Inline::Struct(3)

πŸ“¦
version 0.30 Β· 2 versions
, in fedora 43

πŸ’– Inline::Struct β€” the manual, but make it cute πŸ’–

okay bestie so this is Inline::Struct(3), a page from the User Contributed Perl Documentation β€” and yes I'm gonna walk you through it like we're texting at 1am πŸ’…


✨ NAME ✨

Inline::Struct β€” manipulate C structures directly from Perl. no cap, straight up. 🌸


✨ SYNOPSIS ✨

here's the whole vibe:

use Inline C => 'DATA', structs => ['Foo'];

my $obj = Inline::Struct::Foo->new;
$obj->num(10);
$obj->str("Hello");

print myfunc($obj), "\n";

__END__
__C__
struct Foo {
  int num;
  char *str;
};
typedef struct Foo Foo;

SV *myfunc(Foo *f) {
  return newSVpvf("myfunc: num=%i, str='%s'", f->num, f->str);
}

and this complete program prints:

myfunc: num=10, str='Hello'

like. it just works. 🫢


✨ DESCRIPTION ✨

so Inline::Struct is not a new language. periodt. it's a language extension made to be used by Inline::C. it parses struct definitions and then creates typemaps and XS code that bind each struct into a Perl class. that generated code gets passed to Inline::C, which compiles it the normal way. iconic behaviour honestly. ✨

NOTE: Inline::Struct parses only C-style structs. it does not know about any C++ extensions to structs β€” like scopes, constructors, or methods. zero clue, doesn't care, not invited. if you want that kind of functionality you should use Inline::CPP to parse your structs instead. πŸ’…

🌈 Using Inline::Struct 🌈

Inline::Struct has a Parse::RecDescent grammar to parse C structs. if a struct is recognized, it can be bound to Perl. but if the struct's definition is not recognized β€” usually because it has a member with no typemap β€” it will not be bound to Perl, though it'll still be available from other functions in C or C++. so like, not a total loss, it just doesn't get the Perl glow-up. 😭

here's what a simple struct looks like to a Perl programmer:

Example 1:

use Inline C => <<'END', enable => 'structs';
struct Fraction {
  long numer;
  long denom;
};
END

my $o = Inline::Struct::Fraction->new(4, 3);
print $o->numer, $o->denom, "\n";
$o->numer(4)->denom(7);

after the code above has been compiled, Perl's namespace looks a lot like this:

package Inline::Struct::Fraction;
sub new { }
sub DESTROY { }
sub _KEYS { }
sub _VALUES { }
sub _HASH { }
sub numer { }
sub denom { }

and note that these are actually XS subs written in C, not Perl subs. but that's what it looks like. sneaky. πŸ™ˆ


✨ The Struct Interface ✨

the following sections define the interface of each subroutine. Note: this interface is likely to change in future versions of Inline::Struct. please don't rely on Inline::Struct in production code quite yet β€” it's giving "still in its era". πŸ’€

when a struct is bound by Inline::Struct, a new namespace is created underneath Inline::Struct. so if you have a struct named 'Foo', the package of the Perl class will be 'Inline::Struct::Foo'. πŸŽ€

🌸 new

if no arguments are provided, all fields are zeroed out. if you do provide values, they should be appropriate for the field type, and in the same order as they are defined in the struct. order matters bestie, don't freestyle it. ⭐

🌸 DESTROY

the destructor. it should never be called by the programmer β€” this is called automatically when the Perl variable holding the struct is destroyed. it frees the memory associated with the struct. but if the struct holds pointers to malloc'd memory, those will not be freed. if you run into such a situation, consider using C++ and Inline::CPP instead. lowkey tragic but that's the deal. 😭

🌸 _KEYS

a read-only method β€” it returns a reference to an array containing the names of the fields in the struct. the fields are in the order they appear in the C source code. πŸ¦‹

🌸 _VALUES

a read-only method β€” it returns a reference to an array containing the values of the fields in the struct. the values come back in the same order as the fields. matching set, as they should be. πŸ’œ

🌸 _HASH

a read-only method β€” it returns a reference to a hash, mapping field names to field values. the classic. πŸ’…

🌸 Accessors

for each field in the struct, an accessor method will be created which lets you get or set the value in the struct. if no arguments are provided, the method returns the value of that field. if any arguments are provided, the field is set to the first argument, and the modified structure is returned. which makes setting multiple fields easy:

$o->field1(something)->field2(somethingelse);

chaining? in my struct? it's more likely than you think. ✨


✨ C and C++ Configuration Options ✨

Inline::Struct has no configuration options of its own, but it does provide a new configuration option for C or C++. generous queen. πŸ‘‘

🌈 structs

specifies that structs are to be bound to Perl. there are several meanings to this option, so let's explain with examples:

use Inline C => config => structs => 'Foo';

adds 'Foo' to the list of structs to bind to Perl.

use Inline C => config => structs => ['Foo', 'Bar'];

adds 'Foo' and 'Bar' to the list of structs to bind to Perl.

use Inline C => config => structs => undef;

clears the list of structs to bind to Perl.

use Inline C => config => enable => 'structs';

or

use Inline C => config => structs => 1;

enable binding structs to Perl, without specifying any structs to search for. as shown, this would bind all structs to Perl. all of them. every last one. πŸ”₯

use Inline C => config => disable => 'structs';

or

use Inline C => config => structs => 0;

disable binding structs to Perl. ✨


✨ PERFORMANCE OF STRUCTS AGAINST PERL DATA STRUCTURES ✨

πŸ’– Time

a script, benchmark, that benchmarks a simple C struct against a pure-Perl data structure, is supplied. it should be run a couple of times to get everything cached. a typical results run is as follows:

Faster type          % faster
ISF dnum read        24%
PP dnum write        247%
ISF inum read        39%
PP inum write        231%
ISF str read         18%
PP str write         264%

this shows that reading the struct is faster than a simple object implemented as a hash-ref, while writing to a struct in the current implementation is several times slower. if the Perl object is instead implemented as an array-ref, in the class PP::Foo::Array, the numbers do not change significantly. so like, read = slay, write = not slay. 🫢

πŸ’– Memory

the same script also compares memory usage. a typical results run:

Memory usage
10000 x bless [ 7, "string" ], "main": 34592
10000 x Inline::Struct::Foo->new: 45648
100000 x bless [ 7, "string" ], "main": 139344
100000 x Inline::Struct::Foo->new: 248080
1000000 x bless [ 7, "string" ], "main": 1187024
1000000 x Inline::Struct::Foo->new: 2257968

the memory usage of the struct is around twice as large. twice. it's giving "expensive taste". πŸ’…


✨ SEE ALSO ✨

for more information about using C from Perl, see Inline::C. for more information about using C++ from Perl, see Inline::CPP. go read them bestie, they're right there. πŸ“š


✨ AUTHOR ✨

Neil Watkiss (NEILW@cpan.org) 🌟


Copyright (C) 2001, Neil Watkiss.

this module is free software. it may be used, redistributed and/or modified under the same terms as Perl itself.

see <http://dev.perl.org/licenses/>


and that's the whole page babes πŸŽ€ this one shipped with perl v5.42.0, dated 2025-07-25, so when you see Inline::Struct(3) floating around you know exactly which era it's from. stay structy, stay slay πŸ’–βœ¨πŸ¦‹

πŸ“¦ where this page comes from