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 1.43
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 1.00;
40
41 my $ffi = FFI::Platypus->new( api => 1 );
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 FFI::Platypus::Record
74 Supports:
75
76 C pointers to "struct" types
77 Passing C "struct"s by-value.
78
79 Does not support:
80
81 C "union" types.
82 C arrays of "struct" and "union" types.
83 FFI::C
84 Supports:
85
86 C "struct" and"union" types
87 C arrays of "struct" and "union" types.
88
89 Does not support:
90
91 Passing C "struct"s by-value.
92
93 String members are as of this writing a TODO for FFI::C, but should
94 be coming soon!
95
97 record_layout_1
98 record_layout_1($ffi, $type => $name, ... );
99 record_layout_1(\@ffi_args, $type => $name, ... );
100 record_layout_1($type => $name, ... );
101
102 Define the layout of the record. You may optionally provide an
103 instance of FFI::Platypus as the first argument in order to use its
104 type aliases. Alternatively you may provide constructor arguments that
105 will be passed to the internal platypus instance. Thus this is the
106 same:
107
108 my $ffi = FFI::Platypus->new( lang => 'Rust', api => 1 );
109 record_layout_1( $ffi, ... );
110 # same as:
111 record_layout_1( [ lang => 'Rust' ], ... );
112
113 and this is the same:
114
115 my $ffi = FFI::Platypus->new( api => 1 );
116 record_layout_1( $ffi, ... );
117 # same as:
118 record_layout_1( ... );
119
120 Then you provide members as type/name pairs.
121
122 For each member you declare, "record_layout_1" will create an accessor
123 which can be used to read and write its value. For example imagine a
124 class "Foo":
125
126 package Foo;
127
128 use FFI::Platypus::Record;
129
130 record_layout_1(
131 int => 'bar', # int bar;
132 'string(10)' => 'baz', # char baz[10];
133 );
134
135 You can get and set its fields with like named "bar" and "baz"
136 accessors:
137
138 my $foo = Foo->new;
139
140 $foo->bar(22);
141 my $value = $foo->bar;
142
143 $foo->baz("grimlock\0\0"); # should be 10 characters long
144 my $string_value = $foo->baz; # includes the trailing \0\0
145
146 You can also pass initial values in to the constructor, either passing
147 as a list of key value pairs or by passing a hash reference:
148
149 $foo = Foo->new(
150 bar => 22,
151 baz => "grimlock\0\0",
152 );
153
154 # same as:
155
156 $foo = Foo->new( {
157 bar => 22,
158 baz => "grimlock\0\0",
159 } );
160
161 If there are members of a record that you need to account for in terms
162 of size and alignment, but do not want to have an accessor for, you can
163 use ":" as a place holder for its name:
164
165 record_layout_1(
166 'int' => ':',
167 'string(10)' => 'baz',
168 );
169
170 strings
171
172 So far I've shown fixed length strings. These are declared with the
173 word "string" followed by the length of the string in parentheticals.
174 Fixed length strings are included inside the record itself and do not
175 need to be allocated or deallocated separately from the record.
176 Variable length strings must be allocated on the heap, and thus require
177 a sense of "ownership", that is whomever allocates variable length
178 strings should be responsible for also free'ing them. To handle this,
179 you can add a "ro" or "rw" trait to a string field. The default is
180 "ro", means that you can get, but not set its value:
181
182 package Foo;
183
184 record_layout_1(
185 'string ro' => 'bar', # same type as 'string' and 'string_ro'
186 );
187
188 package main;
189
190 my $foo = Foo->new;
191
192 my $string = $foo->bar; # GOOD
193 $foo->bar("starscream"); # BAD
194
195 If you specify a field is "rw", then you can set its value:
196
197 package Foo;
198
199 record_layout_1(
200 'string rw' => 'bar', # same type as 'string_rw'
201 );
202
203 package main;
204
205 my $foo = Foo->new;
206
207 my $string = $foo->bar; # GOOD
208 $foo->bar("starscream"); # GOOD
209
210 Any string value that is pointed to by the record will be free'd when
211 it falls out of scope, so you must be very careful that any "string rw"
212 fields are not set or modified by C code. You should also take care
213 not to copy any record that has a "rw" string in it because its values
214 will be free'd twice!
215
216 use Clone qw( clone );
217
218 my $foo2 = clone $foo; # BAD bar will be free'd twice
219
220 arrays
221
222 Arrays of integer, floating points and opaque pointers are supported.
223
224 package Foo;
225
226 record_layout_1(
227 'int[10]' => 'bar',
228 );
229
230 my $foo = Foo->new;
231
232 $foo->bar([1,2,3,4,5,6,7,8,9,10]); # sets the values for the array
233 my $list = $foo->bar; # returns a list reference
234
235 $foo->bar(5, -6); # sets the 5th element in the array to -6
236 my $item = $foo->bar(5); gets the 5th element in the array
237
238 record_layout
239 record_layout($ffi, $type => $name, ... );
240 record_layout(\@ffi_args, $type => $name, ... );
241 record_layout($type => $name, ... );
242
243 This function works like "record_layout" except that "api => 0" is used
244 instead of "api => 1". All new code should use "record_layout_1"
245 instead.
246
248 These useful features (and probably more) are missing, and unlikely to
249 be added.
250
251 Unions
252 Nested records
253
254 If you need these features, consider using FFI::C instead.
255
257 FFI::Platypus
258 The main platypus documentation.
259
260 FFI::C
261 Another interface for constructing structured data. It includes
262 support for "union" and array types (which this module does not),
263 but lacks support for passing records by-value.
264
265 FFI::Platypus::Record::TieArray
266 Tied array interface for record array members.
267
268 Convert::Binary::C
269 Another method for constructing and dissecting structured data
270 records.
271
272 pack and unpack
273 Built-in Perl functions for constructing and dissecting structured
274 data records.
275
277 Author: Graham Ollis <plicease@cpan.org>
278
279 Contributors:
280
281 Bakkiaraj Murugesan (bakkiaraj)
282
283 Dylan Cali (calid)
284
285 pipcet
286
287 Zaki Mughal (zmughal)
288
289 Fitz Elliott (felliott)
290
291 Vickenty Fesunov (vyf)
292
293 Gregor Herrmann (gregoa)
294
295 Shlomi Fish (shlomif)
296
297 Damyan Ivanov
298
299 Ilya Pavlov (Ilya33)
300
301 Petr Pisar (ppisar)
302
303 Mohammad S Anwar (MANWAR)
304
305 Håkon Hægland (hakonhagland, HAKONH)
306
307 Meredith (merrilymeredith, MHOWARD)
308
309 Diab Jerius (DJERIUS)
310
311 Eric Brine (IKEGAMI)
312
313 szTheory
314
316 This software is copyright (c) 2015,2016,2017,2018,2019,2020 by Graham
317 Ollis.
318
319 This is free software; you can redistribute it and/or modify it under
320 the same terms as the Perl 5 programming language system itself.
321
322
323
324perl v5.32.1 2021-03-18 FFI::Platypus::Record(3)