1ExtUtils::H2PM(3pm)   User Contributed Perl Documentation  ExtUtils::H2PM(3pm)
2
3
4

NAME

6       "ExtUtils::H2PM" - automatically generate perl modules to wrap C header
7       files
8

DESCRIPTION

10       This module assists in generating wrappers around system
11       functionallity, such as socket() types or ioctl() calls, where the only
12       interesting features required are the values of some constants or
13       layouts of structures normally only known to the C header files. Rather
14       than writing an entire XS module just to contain some constants and
15       pack/unpack functions, this module allows the author to generate, at
16       module build time, a pure perl module containing constant declarations
17       and structure utility functions. The module then requires no XS module
18       to be loaded at run time.
19
20       In comparison to h2ph, "C::Scan::Constants", and so on, this module
21       works by generating a small C program containing printf() lines to
22       output the values of the constants, compiling it, and running it. This
23       allows it to operate without needing tricky syntax parsing or guessing
24       of the contents of C header files.
25
26       It can also automatically build pack/unpack functions for simple
27       structure layouts, whose members are all simple integer or character
28       array fields.  It is not intended as a full replacement of arbitrary
29       code written in XS modules. If structures should contain pointers, or
30       require special custom handling, then likely an XS module will need to
31       be written.
32

FUNCTIONS

34   module
35          module $name;
36
37       Sets the name of the perl module to generate. This will apply a
38       "package" header.
39
40   include
41          include $file;
42
43       Adds a file to the list of headers which will be included by the C
44       program, to obtain the constants or structures from
45
46   constant
47          constant $name, %args;
48
49       Adds a numerical constant.
50
51       The following additional named arguments are also recognised:
52
53       •   name => STRING
54
55           Use the given name for the generated constant function. If not
56           specified, the C name for the constant will be used.
57
58       •   ifdef => STRING
59
60           If present, guard the constant with an "#ifdef STRING" preprocessor
61           macro. If the given string is not defined, no constant will be
62           generated.
63
64   structure
65          structure $name, %args;
66
67       Adds a structure definition. This requires a named argument, "members".
68       This should be an ARRAY ref containing an even number of name-
69       definition pairs. The first of each pair should be a member name. The
70       second should be one of the following structure member definitions.
71
72       The following additional named arguments are also recognised:
73
74       •   pack_func => STRING
75
76       •   unpack_func => STRING
77
78           Use the given names for the generated pack or unpack functions.
79
80       •   with_tail => BOOL
81
82           If true, the structure is a header with more data behind it. The
83           pack function takes an optional extra string value for the data
84           tail, and the unpack function will return an extra string value
85           containing it.
86
87       •   no_length_check => BOOL
88
89           If true, the generated unpack function will not first check the
90           length of its argument before attempting to unpack it. If the
91           buffer is not long enough to unpack all the required values, the
92           remaining ones will not be returned. This may be useful, for
93           example, in cases where various versions of a structure have been
94           designed, later versions adding extra members, but where the exact
95           version found may not be easy to determine beforehand.
96
97       •   arg_style => STRING
98
99           Defines the style in which the functions take arguments or return
100           values.  Defaults to "list", which take or return a list of values
101           in the given order.  The other allowed value is "hashref", where
102           the pack function takes a HASH reference and the unpack function
103           returns one. Each will consist of keys named after the structure
104           members. If a data tail is included, it will use the hash key of
105           "_tail".
106
107       •   ifdef => STRING
108
109           If present, guard the structure with an "#ifdef STRING"
110           preprocessor macro.  If the given string is not defined, no
111           functions will be generated.
112
113       The following structure member definitions are allowed:
114
115       •   member_numeric
116
117           The field contains a single signed or unsigned number. Its size and
118           signedness will be automatically detected.
119
120       •   member_strarray
121
122           The field contains a NULL-padded string of characters. Its size
123           will be automatically detected.
124
125       •   member_constant($code)
126
127           The field contains a single number as for "member_numeric". Instead
128           of consuming/returning a value in the arguments list, this member
129           will be packed from an expression, or asserted that it contains the
130           given value. The string $code will be inserted into the generated
131           pack and unpack functions, so it can be used for constants
132           generated by the "constant" directive.
133
134       The structure definition results in two new functions being created,
135       "pack_$name" and "unpack_$name", where $name is the name of the
136       structure (with the leading "struct" prefix stripped). These behave
137       similarly to the familiar functions such as "pack_sockaddr_in"; the
138       "pack_" function will take a list of fields and return a packed string,
139       the "unpack_" function will take a string and return a list of fields.
140
141   no_export
142   use_export
143   use_export_ok
144          no_export;
145          use_export;
146          use_export_ok;
147
148       Controls the export behaviour of the generated symbols. "no_export"
149       creates symbols that are not exported by their package, they must be
150       used fully- qualified. "use_export" creates symbols that are exported
151       by default.  "use_export_ok" creates symbols that are exported if they
152       are specifically requested at "use" time.
153
154       The mode can be changed at any time to affect only the symbols that
155       follow it. It defaults to "use_export_ok".
156
157   gen_output
158          $perl = gen_output;
159
160       Returns the generated perl code. This is used internally for testing
161       purposes but normally would not be necessary; see instead
162       "write_output".
163
164   write_output
165          write_output $filename;
166
167       Write the generated perl code into the named file. This would normally
168       be used as the last function in the containing script, to generate the
169       output file. In the case of "ExtUtils::MakeMaker" or "Module::Build"
170       invoking the script, the path to the file to be generated should be
171       given in $ARGV[0]. Normally, therefore, the script would end with
172
173        write_output $ARGV[0];
174
175   include_path
176          include_path $path
177
178       Adds an include path to the list of paths used by the compiler
179
180   define
181          define $symbol;
182          define $symbol, $value;
183
184       Adds a symbol to be defined on the compiler's commandline, by using the
185       "-D" option. This is sometimes required to turn on particular optional
186       parts of the included files. An optional value can also be specified.
187

EXAMPLES

189       Normally this module would be used by another module at build time, to
190       construct the relevant constants and structure functions from system
191       headers.
192
193       For example, suppose your operating system defines a new type of
194       socket, which has its own packet and address families, and perhaps some
195       new socket options which are valid on this socket. We can build a
196       module to contain the relevant constants and structure functions by
197       writing, for example:
198
199          #!/usr/bin/perl
200
201          use ExtUtils::H2PM;
202
203          module "Socket::Moonlaser";
204
205          include "moon/laser.h";
206
207          constant "AF_MOONLASER";
208          constant "PF_MOONLASER";
209
210          constant "SOL_MOONLASER";
211
212          constant "MOONLASER_POWER",      name => "POWER";
213          constant "MOONLASER_WAVELENGTH", name => "WAVELENGTH";
214
215          structure "struct laserwl",
216             members => [
217                lwl_nm_coarse => member_numeric,
218                lwl_nm_fine   => member_numeric,
219             ];
220
221          write_output $ARGV[0];
222
223       If we save this script as, say, lib/Socket/Moonlaser.pm.PL, then when
224       the distribution is built, the script will be used to generate the
225       contents of the file lib/Socket/Moonlaser.pm. Once installed, any other
226       code can simply
227
228          use Socket::Moonlaser qw( AF_MOONLASER );
229
230       to import a constant.
231
232       The method described above doesn't allow us any room to actually
233       include other code in the module. Perhaps, as well as these simple
234       constants, we'd like to include functions, documentation, etc... To
235       allow this, name the script instead something like
236       lib/Socket/Moonlaser_const.pm.PL, so that this is the name used for the
237       generated output. The code can then be included in the actual
238       lib/Socket/Moonlaser.pm (which will just be a normal perl module) by
239
240          package Socket::Moonlaser;
241
242          use Socket::Moonlaser_const;
243
244          sub get_power
245          {
246             getsockopt( $_[0], SOL_MOONLASER, POWER );
247          }
248
249          sub set_power
250          {
251             setsockopt( $_[0], SOL_MOONLASER, POWER, $_[1] );
252          }
253
254          sub get_wavelength
255          {
256             my $wl = getsockopt( $_[0], SOL_MOONLASER, WAVELENGTH );
257             defined $wl or return;
258             unpack_laserwl( $wl );
259          }
260
261          sub set_wavelength
262          {
263             my $wl = pack_laserwl( $_[1], $_[2] );
264             setsockopt( $_[0], SOL_MOONLASER, WAVELENGTH, $wl );
265          }
266
267          1;
268
269       Sometimes, the actual C structure layout may not exactly match the
270       semantics we wish to present to perl modules using this extension
271       wrapper. Socket address structures typically contain their address
272       family as the first member, whereas this detail isn't exposed by, for
273       example, the "sockaddr_in" and "sockaddr_un" functions. To cope with
274       this case, the low-level structure packing and unpacking functions can
275       be generated with a different name, and wrapped in higher-level
276       functions in the main code. For example, in Moonlaser_const.pm.PL:
277
278          no_export;
279
280          structure "struct sockaddr_ml",
281             pack_func   => "_pack_sockaddr_ml",
282             unpack_func => "_unpack_sockaddr_ml",
283             members => [
284                ml_family    => member_numeric,
285                ml_lat_deg   => member_numeric,
286                ml_long_deg  => member_numeric,
287                ml_lat_fine  => member_numeric,
288                ml_long_fine => member_numeric,
289             ];
290
291       This will generate a pack/unpack function pair taking or returning five
292       arguments; these functions will not be exported. In our main
293       Moonlaser.pm file we can wrap these to actually expose a different API:
294
295          sub pack_sockaddr_ml
296          {
297             @_ == 2 or croak "usage: pack_sockaddr_ml(lat, long)";
298             my ( $lat, $long ) = @_;
299
300             return _pack_sockaddr_ml( AF_MOONLASER, int $lat, int $long,
301               ($lat - int $lat) * 1_000_000, ($long - int $long) * 1_000_000);
302          }
303
304          sub unpack_sockaddr_ml
305          {
306             my ( $family, $lat, $long, $lat_fine, $long_fine ) =
307                _unpack_sockaddr_ml( $_[0] );
308
309             $family == AF_MOONLASER or croak "expected family AF_MOONLASER";
310
311             return ( $lat + $lat_fine/1_000_000, $long + $long_fine/1_000_000 );
312          }
313
314       Sometimes, a structure will contain members which are themselves
315       structures.  Suppose a different definition of the above address, which
316       at the C layer is defined as
317
318          struct angle
319          {
320             short         deg;
321             unsigned long fine;
322          };
323
324          struct sockaddr_ml
325          {
326             short        ml_family;
327             struct angle ml_lat, ml_long;
328          };
329
330       We can instead "flatten" this structure tree to obtain the five fields
331       by naming the sub-members of the outer structure:
332
333          structure "struct sockaddr_ml",
334             members => [
335                "ml_family"    => member_numeric,
336                "ml_lat.deg"   => member_numeric,
337                "ml_lat.fine"  => member_numeric,
338                "ml_long.deg"  => member_numeric,
339                "ml_long.fine" => member_numeric,
340             ];
341

TODO

343       •   Consider more structure members. With strings comes the requirement
344           to have members that store a size. This requires cross-referential
345           members. And while we're at it it might be nice to have constant
346           members; fill in constants without consuming arguments when
347           packing, assert the right value on unpacking.
348

AUTHOR

350       Paul Evans <leonerd@leonerd.org.uk>
351
352
353
354perl v5.38.0                      2023-07-20               ExtUtils::H2PM(3pm)
Impressum