Commit | Line | Data |
4633a7c4 |
1 | =head1 NAME |
2 | |
3 | perlXStut - Tutorial for XSUB's |
4 | |
5 | =head1 DESCRIPTION |
6 | |
7 | This tutorial will educate the reader on the steps involved in creating |
8 | a Perl 5 extension. The reader is assumed to have access to L<perlguts> and |
9 | L<perlxs>. |
10 | |
11 | This tutorial starts with very simple examples and becomes more complex, |
12 | bringing in more features that are available. Thus, certain statements |
13 | towards the beginning may be incomplete. The reader is encouraged to |
14 | read the entire document before lambasting the author about apparent |
15 | mistakes. |
16 | |
17 | This tutorial is still under construction. Constructive comments |
18 | are welcome. |
19 | |
20 | =head1 EXAMPLE 1 |
21 | |
22 | Our first extension will be very simple. When we call the routine in the |
23 | extension, it will print out a well-known message and terminate. |
24 | |
cb1a09d0 |
25 | Run C<h2xs -A -n Test1>. This creates a directory named Test1, possibly under |
4633a7c4 |
26 | ext/ if it exists in the current working directory. Four files will be |
27 | created in the Test1 dir: MANIFEST, Makefile.PL, Test1.pm, Test1.xs. |
28 | |
29 | The MANIFEST file should contain the names of the four files created. |
30 | |
31 | The file Makefile.PL should look something like this: |
32 | |
33 | use ExtUtils::MakeMaker; |
34 | # See lib/ExtUtils/MakeMaker.pm for details of how to influence |
35 | # the contents of the Makefile that is written. |
36 | WriteMakefile( |
37 | 'NAME' => 'Test1', |
38 | 'VERSION' => '0.1', |
39 | 'LIBS' => [''], # e.g., '-lm' |
40 | 'DEFINE' => '', # e.g., '-DHAVE_SOMETHING' |
41 | 'INC' => '', # e.g., '-I/usr/include/other' |
42 | ); |
43 | |
44 | The file Test1.pm should look something like this: |
45 | |
46 | package Test1; |
47 | |
48 | require Exporter; |
49 | require DynaLoader; |
50 | |
51 | @ISA = qw(Exporter DynaLoader); |
52 | # Items to export into callers namespace by default. Note: do not export |
53 | # names by default without a very good reason. Use EXPORT_OK instead. |
54 | # Do not simply export all your public functions/methods/constants. |
55 | @EXPORT = qw( |
56 | |
57 | ); |
58 | bootstrap Test1; |
59 | |
60 | # Preloaded methods go here. |
61 | |
62 | # Autoload methods go after __END__, and are processed by the autosplit program. |
63 | |
64 | 1; |
65 | __END__ |
66 | |
67 | And the Test1.xs file should look something like this: |
68 | |
69 | #include "EXTERN.h" |
70 | #include "perl.h" |
71 | #include "XSUB.h" |
72 | |
73 | MODULE = Test1 PACKAGE = Test1 |
74 | |
75 | Let's edit the .xs file by adding this to the end of the file: |
76 | |
77 | void |
78 | hello() |
79 | |
80 | CODE: |
81 | printf("Hello, world!\n"); |
82 | |
cb1a09d0 |
83 | Now we'll run C<perl Makefile.PL>. This will create a real Makefile, |
4633a7c4 |
84 | which make needs. It's output looks something like: |
85 | |
86 | % perl Makefile.PL |
87 | Checking if your kit is complete... |
88 | Looks good |
89 | Writing Makefile for Test1 |
90 | % |
91 | |
92 | Now, running make will produce output that looks something like this: |
93 | |
94 | % make |
95 | mkdir ./blib |
96 | mkdir ./blib/auto |
97 | mkdir ./blib/auto/Test1 |
98 | perl xsubpp -typemap typemap Test1.xs >Test1.tc && mv Test1.tc Test1.c |
99 | cc -c Test1.c |
100 | Running Mkbootstrap for Test1 () |
101 | chmod 644 Test1.bs |
102 | LD_RUN_PATH="" ld -o ./blib/auto/Test1/Test1.sl -b Test1.o |
103 | chmod 755 ./blib/auto/Test1/Test1.sl |
104 | cp Test1.bs ./blib/auto/Test1/Test1.bs |
105 | chmod 644 ./blib/auto/Test1/Test1.bs |
106 | cp Test1.pm ./blib/Test1.pm |
107 | chmod 644 ./blib/Test1.pm |
108 | |
109 | Now we'll create a test script, test1.pl in the Test1 directory. It should |
110 | look like this: |
111 | |
112 | #! /usr/local/bin/perl |
113 | |
114 | BEGIN { unshift(@INC, "./blib") } |
115 | |
116 | use Test1; |
117 | |
118 | Test1::hello(); |
119 | |
120 | Now we run the script and we should see the following output: |
121 | |
122 | % perl test1.pl |
123 | Hello, world! |
124 | % |
125 | |
126 | =head1 EXAMPLE 2 |
127 | |
128 | Now let's create a simple extension that will take a single argument and |
129 | return 0 if the argument is even, 1 if the argument is odd. |
130 | |
cb1a09d0 |
131 | Run C<h2xs -A -n Test2>. This will create a Test2 directory with a file |
4633a7c4 |
132 | Test2.xs underneath it. Add the following to the end of the XS file: |
133 | |
134 | int |
135 | is_even(input) |
136 | int input |
137 | |
138 | CODE: |
139 | RETVAL = input % 2; |
140 | |
141 | OUTPUT: |
142 | RETVAL |
143 | |
144 | (Note that the line after the declaration of is_even is indented one tab |
145 | stop. Although there is a tab between "int" and "input", this can be any |
146 | amount of white space. Also notice that there is no semi-colon following |
147 | the "declaration" of the variable input) |
148 | |
149 | Now perform the same steps before, generating a Makefile from the |
150 | Makefile.PL file, and running make. |
151 | |
152 | Our test file test2.pl will now look like: |
153 | |
154 | BEGIN { unshift(@INC, "./blib"); } |
155 | |
156 | use Test2; |
157 | |
158 | $a = &Test2::is_even(2); |
159 | $b = &Test2::is_even(3); |
160 | |
161 | print "\$a is $a, \$b is $b\n"; |
162 | |
163 | The output should look like: |
164 | |
165 | % perl test2.pl |
166 | $a is 0, $b is 1 |
167 | % |
168 | |
169 | =head1 WHAT HAS GONE ON? |
170 | |
171 | The program h2xs is the starting point for creating extensions. In later |
172 | examples, we'll see how we can use h2xs to read header files and generate |
173 | templates to connect to C routines. |
174 | |
175 | h2xs creates a number of files in the extension directory. The file |
176 | Makefile.PL is a perl script which will generate a true Makefile to build |
177 | the extension. We'll take a closer look at it later. |
178 | |
179 | The files <extension>.pm and <extension>.xs contain the meat of the extension. |
180 | The .xs file holds the C routines that make up the extension. The .pm file |
181 | contains routines that tells Perl how to load your extension. |
182 | |
183 | Generating the invoking the Makefile created a directory blib in the current |
184 | working directory. This directory will contain the shared library that we |
185 | will build. Once we have tested it, we can install it into its final location. |
186 | |
187 | Finally, our test scripts do two important things. First of all, they place |
188 | the directory "blib" at the head of the @INC array. Placing this inside a |
189 | BEGIN block assures us that Perl will look in the blib directory hierarchy |
190 | before looking in the system directories. This could be important if you are |
191 | upgrading an already-existing extension and do not want to disturb the system |
192 | version until you are ready to install it. |
193 | |
194 | Second, the test scripts tell Perl to C<use extension;>. When Perl sees this, |
195 | it searches for a .pm file of the same name in the various directories kept |
196 | in the @INC array. If it cannot be found, perl will die with an error that |
197 | will look something like: |
198 | |
199 | Can't locate Test2.pm in @INC at ./test2.pl line 5. |
200 | BEGIN failed--compilation aborted at ./test2.pl line 5. |
201 | |
202 | The .pm file tells perl that it will need the Exporter and Dynamic Loader |
203 | extensions. It then sets the @ISA array, which is used for looking up |
204 | methods that might not exist in the current package, and finally tells perl |
205 | to bootstrap the module. Perl will call its dynamic loader routine and load |
206 | the shared library. |
207 | |
208 | The @EXPORT array in the .pm file tells Perl which of the extension's |
209 | routines should be placed into the calling package's namespace. In our two |
210 | examples so far, we have not modified the @EXPORT array, so our test |
211 | scripts must call the routines by their complete name (e.g., Test1::hello). |
212 | If we placed the name of the routine in the @EXPORT array, so that the |
213 | .pm file looked like: |
214 | |
215 | @EXPORT = qw( hello ); |
216 | |
217 | Then the hello routine would also be callable from the "main" package. |
218 | We could therefore change test1.pl to look like: |
219 | |
220 | #! /usr/local/bin/perl |
221 | |
222 | BEGIN { unshift(@INC, "./blib") } |
223 | |
224 | use Test1; |
225 | |
226 | hello(); |
227 | |
228 | And we would get the same output, "Hello, world!". |
229 | |
230 | Most of the time you do not want to export the names of your extension's |
231 | subroutines, because they might accidentally clash with other subroutines |
232 | from other extensions or from the calling program itself. |
233 | |
234 | =head1 EXAMPLE 3 |
235 | |
236 | Our third extension will take one argument as its input, round off that |
237 | value, and set the argument to the rounded value. |
238 | |
cb1a09d0 |
239 | Run C<h2xs -A -n Test3>. This will create a Test3 directory with a file |
4633a7c4 |
240 | Test3.xs underneath it. Add the following to the end of the XS file: |
241 | |
242 | void |
243 | round(arg) |
244 | double arg |
245 | |
246 | CODE: |
247 | if (arg > 0.0) { |
248 | arg = floor(arg + 0.5); |
249 | } else if (arg < 0.0) { |
250 | arg = ceil(arg - 0.5); |
251 | } else { |
252 | arg = 0.0; |
253 | } |
254 | OUTPUT: |
255 | arg |
256 | |
257 | Edit the file Makefile.PL so that the corresponding line looks like this: |
258 | |
259 | 'LIBS' => ['-lm'], # e.g., '-lm' |
260 | |
261 | Generate the Makefile and run make. The test script test3.pl looks like: |
262 | |
263 | #! /usr/local/bin/perl |
264 | |
265 | BEGIN { unshift(@INC, "./blib"); } |
266 | |
267 | use Test3; |
268 | |
269 | foreach $i (-1.4, -0.5, 0.0, 0.4, 0.5) { |
270 | $j = $i; |
271 | &Test3::round($j); |
272 | print "Rounding $i results in $j\n"; |
273 | } |
274 | |
275 | print STDERR "Trying to round a constant -- "; |
276 | &Test3::round(2.0); |
277 | |
278 | Notice the output from trying to send a constant in to the routine. Perl |
279 | reports: |
280 | |
281 | Modification of a read-only value attempted at ./test3.pl line 15. |
282 | |
283 | Perl won't let you change the value of two to, say, three, unlike a FORTRAN |
284 | compiler from long, long ago! |
285 | |
286 | =head1 WHAT'S NEW HERE? |
287 | |
288 | Two things are new here. First, we've made some changes to Makefile.PL. |
289 | In this case, we've specified an extra library to link in, in this case the |
290 | math library, libm. We'll talk later about how to write XSUBs that can call |
291 | every routine in a library. |
292 | |
293 | Second, the value of the function is being passed back not as the function's |
294 | return value, but through the same variable that was passed into the function. |
295 | |
296 | =head1 INPUT AND OUTPUT PARAMETERS |
297 | |
298 | You specify the parameters that will be passed into the XSUB just after you |
299 | declare the function return value and name. The list of parameters looks |
300 | very C-like, but the lines must be indented by a tab stop, and each line |
301 | may not have an ending semi-colon. |
302 | |
303 | The list of output parameters occurs after the OUTPUT: directive. The use |
304 | of RETVAL tells Perl that you wish to send this value back as the return |
305 | value of the XSUB function. Otherwise, you specify which variables used |
306 | in the XSUB function should be placed into the respective Perl variables |
307 | passed in. |
308 | |
309 | =head1 THE XSUBPP COMPILER |
310 | |
311 | The compiler xsubpp takes the XS code in the .xs file and converts it into |
312 | C code, placing it in a file whose suffix is .c. The C code created makes |
313 | heavy use of the C functions within Perl. |
314 | |
315 | =head1 THE TYPEMAP FILE |
316 | |
317 | The xsubpp compiler uses rules to convert from Perl's data types (scalar, |
318 | array, etc.) to C's data types (int, char *, etc.). These rules are stored |
319 | in the typemap file ($PERLLIB/ExtUtils/typemap). This file is split into |
320 | three parts. |
321 | |
322 | The first part attempts to map various C data types to a coded flag, which |
323 | has some correspondence with the various Perl types. The second part contains |
324 | C code which xsubpp uses for input parameters. The third part contains C |
325 | code which xsubpp uses for output parameters. We'll talk more about the |
326 | C code later. |
327 | |
328 | Let's now take a look at the .c file created for the Test3 extension. |
329 | |
330 | /* |
331 | * This file was generated automatically by xsubpp version 1.9 from the |
332 | * contents of Test3.xs. Don't edit this file, edit Test3.xs instead. |
333 | * |
334 | * ANY CHANGES MADE HERE WILL BE LOST! |
335 | * |
336 | */ |
337 | |
338 | #include "EXTERN.h" |
339 | #include "perl.h" |
340 | #include "XSUB.h" |
341 | |
342 | |
343 | XS(XS_Test3_round) |
344 | { |
345 | dXSARGS; |
346 | if (items != 1) { |
347 | croak("Usage: Test3::round(arg)"); |
348 | } |
349 | { |
350 | double arg = (double)SvNV(ST(0)); /* XXXXX */ |
351 | |
352 | if (arg > 0.0) { |
353 | arg = floor(arg + 0.5); |
354 | } else if (arg < 0.0) { |
355 | arg = ceil(arg - 0.5); |
356 | } |
357 | |
358 | sv_setnv(ST(0), (double)arg); /* XXXXX */ |
359 | } |
360 | XSRETURN(1); |
361 | } |
362 | |
363 | XS(boot_Test3) |
364 | { |
365 | dXSARGS; |
366 | char* file = __FILE__; |
367 | |
368 | newXS("Test3::round", XS_Test3_round, file); |
369 | ST(0) = &sv_yes; |
370 | XSRETURN(1); |
371 | } |
372 | |
373 | Notice the two lines marked with "XXXXX". If you check the first section of |
374 | the typemap file, you'll see that doubles are of type T_DOUBLE. In the |
375 | INPUT section, an argument that is T_DOUBLE is assigned to the variable |
376 | arg by calling the routine SvNV on something, then casting it to double, |
377 | then assigned to the variable arg. Similarly, in the OUTPUT section, |
378 | once arg has its final value, it is passed to the sv_setnv function to |
379 | be passed back to the calling subroutine. These two functions are explained |
380 | in perlguts; we'll talk more later about what that "ST(0)" means in the |
381 | section on the argument stack. |
382 | |
383 | =head1 WARNING |
384 | |
385 | In general, it's not agood idea to write extensions that modify their input |
386 | parameters, as in Example 3. However, in order to better accomodate calling |
387 | pre-existing C routines, which often do modify their input parameters, |
388 | this behavior is tolerated. The next example will show to do this. |
389 | |
390 | =head1 EXAMPLE 4 |
391 | |
392 | We'll now show how we can call routines in libraries, such as the curses |
393 | screen handling package, or a DBM module like GDBM. Each of these libraries |
394 | has a header file from which we will generate an XS template that we'll then |
395 | fine-tune. |
396 | |
397 | Rather than attempt to find a library that exists on all systems, we'll |
398 | first create our own C library, then create an XSUB to it. |
399 | |
400 | Let's create the files libtest4.h and libtest4.c as follows: |
401 | |
402 | /* libtest4.h */ |
403 | |
404 | #define TESTVAL 4 |
405 | |
406 | extern int test4(int, long, const char*); |
407 | |
408 | /* libtest4.c */ |
409 | |
410 | #include <stdlib.h> |
411 | #include "./libtest4.h" |
412 | |
413 | int |
414 | test4(a, b, c) |
415 | int a; |
416 | long b; |
417 | const char * c; |
418 | { |
419 | return (a + b + atof(c) + TESTVAL); |
420 | } |
421 | |
422 | Now let's compile it into a library. Since we'll be eventually using this |
423 | archive to create a shared library, be sure to use the correct flags to |
424 | generate position-independent code. In HP-UX, that's: |
425 | |
426 | % cc -Aa -D_HPUX_SOURCE -c +z libtest4.c |
427 | % ar cr libtest4.a libtest4.o |
428 | |
429 | Now let's move the libtest4.h and libtest.a files into a sub-directory under |
430 | /tmp, so we don't interfere with anything. |
431 | |
432 | % mkdir /tmp/test4 |
433 | % mkdir /tmp/test4/include |
434 | % mkdir /tmp/test4/lib |
435 | % cp libtest4.h /tmp/test4/include |
436 | % cp libtest4.a /tmp/test4/lib |
437 | |
438 | Okay, now that we have a header file and a library, let's begin actually |
439 | writing the extension. |
440 | |
cb1a09d0 |
441 | Run C<h2xs -n Test4 /tmp/test4/include/libtest4.h> (notice we are no longer |
442 | specifying B<-A> as an argument). This will create a Test4 directory with a file |
443 | F<Test4.xs> underneath it. If we look at it now, we'll see some interesting |
4633a7c4 |
444 | things have been added to the various files. |
445 | |
446 | =over 2 |
447 | |
448 | =item * |
449 | |
450 | In the .xs file, there's now a #include declaration with the full path to |
451 | the libtest4.h header file. |
452 | |
453 | =item * |
454 | |
455 | There's now some new C code that's been added to the .xs file. The purpose |
456 | of the C<constant> routine is to make the values that are #define'd in the |
457 | header file available to the Perl script by calling C<&main::TESTVAL>. |
458 | There's also some XS code to allow calls to the C<constant> routine. |
459 | |
460 | =item * |
461 | |
462 | The .pm file has exported the name TESTVAL in the @EXPORT array. This |
463 | could lead to name clashes. A good rule of thumb is that if the #define |
464 | is only going to be used by the C routines themselves, and not by the user, |
465 | they should be removed from the @EXPORT array. Alternately, if you don't |
466 | mind using the "fully qualified name" of a variable, you could remove most |
467 | or all of the items in the @EXPORT array. |
468 | |
469 | =back |
470 | |
471 | Let's now add a definition for the routine in our library. Add the following |
472 | code to the end of the .xs file: |
473 | |
474 | int |
475 | test4(a,b,c) |
476 | int a |
477 | long b |
478 | const char * c |
479 | |
480 | Now we also need to create a typemap file because the default Perl doesn't |
481 | currently support the const char * type. Create a file called typemap and |
482 | place the following in it: |
483 | |
484 | const char * T_PV |
485 | |
486 | Now we must tell our Makefile template where our new library is. Edit the |
487 | Makefile.PL and change the following line: |
488 | |
489 | 'LIBS' => ['-ltest4 -L/tmp/test4'], # e.g., '-lm' |
490 | |
491 | This specifies that we want the library test4 linked into our XSUB, and that |
492 | it should also look in the directory /tmp/test4. |
493 | |
494 | Let's also change the following line in the Makefile.PL to this: |
495 | |
496 | 'INC' => '-I/tmp/test/include', # e.g., '-I/usr/include/other' |
497 | |
498 | and also change the #include in test4.xs to be: |
499 | |
500 | #include <libtest4.h> |
501 | |
502 | Now we don't have to specify the absolute path of the header file in the |
503 | .xs file, relying on the Makefile to tell the compiler where to find the |
504 | header files. This is generally considered a Good Thing. |
505 | |
506 | Okay, let's create the Makefile, and run make. You can ignore a message that |
507 | may look like: |
508 | |
509 | Warning (non-fatal): No library found for -ltest4 |
510 | |
511 | If you forgot to create the typemap file, you might see output that looks |
512 | like this: |
513 | |
514 | Error: 'const char *' not in typemap in test4.xs, line 102 |
515 | |
516 | This error means that you have used a C datatype that xsubpp doesn't know |
517 | how to convert between Perl and C. You'll have to create a typemap file to |
518 | tell xsubpp how to do the conversions. |
519 | |
520 | =head1 Author |
521 | |
522 | Jeff Okamoto |
523 | |
524 | =head1 Last Changed |
525 | |
526 | 1995/11/20 |
527 | |
528 | Jeff Okamoto |
529 | F<E<lt>okamoto@hpcc123.corp.hp.comE<gt>> |