1FFI::Platypus::Record(3U)ser Contributed Perl DocumentatiFoFnI::Platypus::Record(3)
2
3
4
6 FFI::Platypus::Record - FFI support for structured records data
7
9 version 2.08
10
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
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
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
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
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
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)