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