1FFI::Platypus::Record(3U)ser Contributed Perl DocumentatiFoFnI::Platypus::Record(3)
2
3
4

NAME

6       FFI::Platypus::Record - FFI support for structured records data
7

VERSION

9       version 2.08
10

SYNOPSIS

12       C:
13
14        struct my_person {
15          int         age;
16          const char  title[3];
17          const char *name
18        };
19
20        void process_person(struct my_person *person)
21        {
22          /* ... */
23        }
24
25       Perl:
26
27        package MyPerson;
28
29        use FFI::Platypus::Record;
30
31        record_layout_1(
32          'int'       => 'age',
33          'string(3)' => 'title',
34          'string rw' => 'name',
35        );
36
37        package main;
38
39        use FFI::Platypus 2.00;
40
41        my $ffi = FFI::Platypus->new( api => 2 );
42        $ffi->lib("myperson.so");
43        $ffi->type("record(MyPerson)" => 'MyPerson');
44
45        my $person = MyPerson->new(
46          age   => 40,
47          title => "Mr.",
48          name  => "John Smith",
49        );
50
51        $ffi->attach( process_person => [ 'MyPerson*' ] => 'void' );
52
53        process_person($person);
54
55        $person->age($person->age + 1); # another year older
56
57        process_person($person);
58

DESCRIPTION

60       [version 0.21]
61
62       This module provides a mechanism for building classes that can be used
63       to mange structured data records (known as C as "structs" and in some
64       languages as "records").  A structured record is a series of bytes that
65       have structure understood by the C or other foreign language library
66       that you are interfacing with.  It is designed for use with FFI and
67       FFI::Platypus, though it may have other applications.
68
69       Before you get to deep into using this class you should also consider
70       the FFI::C, which provides some overlapping functionality.  Briefly, it
71       comes down to this:
72
73       (The tl;dr is: use this class when you need to pass by value (since
74       FFI::C does not support pass by value) and use FFI::C in all other
75       circumstances).
76
77       FFI::Platypus::Record
78           Supports:
79
80           C pointers to "struct" types
81           Passing C "struct"s by-value.
82
83           Does not support:
84
85           C "union" types.
86           C arrays of "struct" and "union" types.
87       FFI::C
88           Supports:
89
90           C "struct" and"union" types
91           C arrays of "struct" and "union" types.
92
93           Does not support:
94
95           Passing C "struct"s by-value.
96
97           String members are as of this writing a TODO for FFI::C, but should
98           be coming soon!
99

FUNCTIONS

101   record_layout_1
102        record_layout_1($ffi, $type => $name, ... );
103        record_layout_1(\@ffi_args, $type => $name, ... );
104        record_layout_1($type => $name, ... );
105
106       Define the layout of the record.  You may optionally provide an
107       instance of FFI::Platypus as the first argument in order to use its
108       type aliases.  Alternatively you may provide constructor arguments that
109       will be passed to the internal platypus instance.  Thus this is the
110       same:
111
112        my $ffi = FFI::Platypus->new( lang => 'Rust', api => 2 );
113        record_layout_1( $ffi, ... );
114        # same as:
115        record_layout_1( [ lang => 'Rust' ], ... );
116
117       and this is the same:
118
119        my $ffi = FFI::Platypus->new( api => 2 );
120        record_layout_1( $ffi, ... );
121        # same as:
122        record_layout_1( ... );
123
124       Then you provide members as type/name pairs.
125
126       For each member you declare, "record_layout_1" will create an accessor
127       which can be used to read and write its value. For example imagine a
128       class "Foo":
129
130        package Foo;
131
132        use FFI::Platypus::Record;
133
134        record_layout_1(
135          int          => 'bar',  #  int bar;
136          'string(10)' => 'baz',  #  char baz[10];
137        );
138
139       You can get and set its fields with like named "bar" and "baz"
140       accessors:
141
142        my $foo = Foo->new;
143
144        $foo->bar(22);
145        my $value = $foo->bar;
146
147        $foo->baz("grimlock\0\0"); # should be 10 characters long
148        my $string_value = $foo->baz; # includes the trailing \0\0
149
150       You can also pass initial values in to the constructor, either passing
151       as a list of key value pairs or by passing a hash reference:
152
153        $foo = Foo->new(
154          bar => 22,
155          baz => "grimlock\0\0",
156        );
157
158        # same as:
159
160        $foo = Foo->new( {
161          bar => 22,
162          baz => "grimlock\0\0",
163        } );
164
165       If there are members of a record that you need to account for in terms
166       of size and alignment, but do not want to have an accessor for, you can
167       use ":" as a place holder for its name:
168
169        record_layout_1(
170          'int'        => ':',
171          'string(10)' => 'baz',
172        );
173
174       strings
175
176       So far I've shown fixed length strings.  These are declared with the
177       word "string" followed by the length of the string in parentheticals.
178       Fixed length strings are included inside the record itself and do not
179       need to be allocated or deallocated separately from the record.
180       Variable length strings must be allocated on the heap, and thus require
181       a sense of "ownership", that is whomever allocates variable length
182       strings should be responsible for also free'ing them.  To handle this,
183       you can add a "ro" or "rw" trait to a string field.  The default is
184       "ro", means that you can get, but not set its value:
185
186        package Foo;
187
188        record_layout_1(
189          'string ro' => 'bar',  # same type as 'string' and 'string_ro'
190        );
191
192        package main;
193
194        my $foo = Foo->new;
195
196        my $string = $foo->bar;  # GOOD
197        $foo->bar("starscream"); # BAD
198
199       If you specify a field is "rw", then you can set its value:
200
201        package Foo;
202
203        record_layout_1(
204          'string rw' => 'bar',  # same type as 'string_rw'
205        );
206
207        package main;
208
209        my $foo = Foo->new;
210
211        my $string = $foo->bar;  # GOOD
212        $foo->bar("starscream"); # GOOD
213
214       Any string value that is pointed to by the record will be free'd when
215       it falls out of scope, so you must be very careful that any "string rw"
216       fields are not set or modified by C code.  You should also take care
217       not to copy any record that has a "rw" string in it because its values
218       will be free'd twice!
219
220        use Clone qw( clone );
221
222        my $foo2 = clone $foo;  # BAD  bar will be free'd twice
223
224       arrays
225
226       Arrays of integer, floating points and opaque pointers are supported.
227
228        package Foo;
229
230        record_layout_1(
231          'int[10]' => 'bar',
232        );
233
234        my $foo = Foo->new;
235
236        $foo->bar([1,2,3,4,5,6,7,8,9,10]); # sets the values for the array
237        my $list = $foo->bar;  # returns a list reference
238
239        $foo->bar(5, -6); # sets the 5th element in the array to -6
240        my $item = $foo->bar(5); gets the 5th element in the array
241
242   record_layout
243        record_layout($ffi, $type => $name, ... );
244        record_layout(\@ffi_args, $type => $name, ... );
245        record_layout($type => $name, ... );
246
247       This function works like "record_layout" except that "api => 0" is used
248       instead of "api => 1".  All new code should use "record_layout_1"
249       instead.
250

CAVEATS

252       These useful features (and probably more) are missing, and unlikely to
253       be added.
254
255       Unions
256       Nested records
257
258       If you need these features, consider using FFI::C instead.
259

SEE ALSO

261       FFI::Platypus
262           The main platypus documentation.
263
264       FFI::C
265           Another interface for constructing structured data.  It includes
266           support for "union" and array types (which this module does not),
267           but lacks support for passing records by-value.
268
269       FFI::Platypus::Record::TieArray
270           Tied array interface for record array members.
271
272       Convert::Binary::C
273           Another method for constructing and dissecting structured data
274           records.
275
276       pack and unpack
277           Built-in Perl functions for constructing and dissecting structured
278           data records.
279

AUTHOR

281       Author: Graham Ollis <plicease@cpan.org>
282
283       Contributors:
284
285       Bakkiaraj Murugesan (bakkiaraj)
286
287       Dylan Cali (calid)
288
289       pipcet
290
291       Zaki Mughal (zmughal)
292
293       Fitz Elliott (felliott)
294
295       Vickenty Fesunov (vyf)
296
297       Gregor Herrmann (gregoa)
298
299       Shlomi Fish (shlomif)
300
301       Damyan Ivanov
302
303       Ilya Pavlov (Ilya33)
304
305       Petr Písař (ppisar)
306
307       Mohammad S Anwar (MANWAR)
308
309       Håkon Hægland (hakonhagland, HAKONH)
310
311       Meredith (merrilymeredith, MHOWARD)
312
313       Diab Jerius (DJERIUS)
314
315       Eric Brine (IKEGAMI)
316
317       szTheory
318
319       José Joaquín Atria (JJATRIA)
320
321       Pete Houston (openstrike, HOUSTON)
322
324       This software is copyright (c) 2015-2022 by Graham Ollis.
325
326       This is free software; you can redistribute it and/or modify it under
327       the same terms as the Perl 5 programming language system itself.
328
329
330
331perl v5.36.1                      2023-05-15          FFI::Platypus::Record(3)
Impressum