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