| 1 | =head1 NAME |
| 2 | |
| 3 | C Cookbook - A Cornucopia of Inline C Recipes |
| 4 | |
| 5 | =cut -------------------------------------------------------------------------- |
| 6 | |
| 7 | =head1 DESCRIPTION |
| 8 | |
| 9 | It's a lot easier for most of us to cook a meal from a recipe, rather |
| 10 | than just throwing things into a pot until something edible forms. So it |
| 11 | is with programming as well. C<Inline.pm> makes C programming for Perl |
| 12 | as easy as possible. Having a set of easy to understand samples, makes |
| 13 | it simpler yet. |
| 14 | |
| 15 | This Cookbook is intended to be an evergrowing repository of small yet |
| 16 | complete coding examples; each showing how to accomplish a particular |
| 17 | task with Inline. Each example is followed by a short discussion, |
| 18 | explaining in detail the particular features that are being |
| 19 | demonstrated. |
| 20 | |
| 21 | Many of these recipes are apdapted from email discussions I have had |
| 22 | with Inline users around the world. It has been my experience so far, |
| 23 | that Inline provides an elegant solution to almost all problems |
| 24 | involving Perl and C. |
| 25 | |
| 26 | Bon Appetit! |
| 27 | |
| 28 | =cut -------------------------------------------------------------------------- |
| 29 | |
| 30 | =head1 Appetizers |
| 31 | |
| 32 | =cut -------------------------------------------------------------------------- |
| 33 | |
| 34 | =head2 Hello, world |
| 35 | |
| 36 | =over 4 |
| 37 | |
| 38 | =item Problem |
| 39 | |
| 40 | It seems that the first thing any programmer wants to do when he learns |
| 41 | a new programming technique is to use it to greet the Earth. How can I |
| 42 | do this using Inline? |
| 43 | |
| 44 | =item Solution |
| 45 | |
| 46 | use Inline C => <<'END_C'; |
| 47 | |
| 48 | void greet() { |
| 49 | printf("Hello, world\n"); |
| 50 | } |
| 51 | END_C |
| 52 | |
| 53 | greet; |
| 54 | |
| 55 | =item Discussion |
| 56 | |
| 57 | Nothing too fancy here. We define a single C function C<greet()> which |
| 58 | prints a message to STDOUT. One thing to note is that since the Inline |
| 59 | code comes before the function call to C<greet>, we can call it as a |
| 60 | bareword (no parentheses). |
| 61 | |
| 62 | =item See Also |
| 63 | |
| 64 | See L<Inline> and L<Inline::C> for basic info about C<Inline.pm>. |
| 65 | |
| 66 | =item Credits |
| 67 | |
| 68 | Brian Kernigan |
| 69 | |
| 70 | Dennis Ritchie |
| 71 | |
| 72 | =back |
| 73 | |
| 74 | =cut -------------------------------------------------------------------------- |
| 75 | |
| 76 | =head2 One Liner |
| 77 | |
| 78 | =over 4 |
| 79 | |
| 80 | =item Problem |
| 81 | |
| 82 | A concept is valid in Perl only if it can be shown to work in one line. |
| 83 | Can Inline reduce the complexities of Perl/C interaction to a one-liner? |
| 84 | |
| 85 | =item Solution |
| 86 | |
| 87 | perl -e 'use Inline C=>q{void greet(){printf("Hello, world\n");}};greet' |
| 88 | |
| 89 | =item Discussion |
| 90 | |
| 91 | Try doing that in XS :-) |
| 92 | |
| 93 | =item See Also |
| 94 | |
| 95 | My email signature of late is: |
| 96 | |
| 97 | perl -le 'use Inline C=>q{SV*JAxH(char*x){return newSVpvf("Just Another %s Hacker",x);}};print JAxH+Perl' |
| 98 | |
| 99 | A bit fancier but a few bytes too long to qualify as a true one liner :-( |
| 100 | |
| 101 | =item Credits |
| 102 | |
| 103 | "Eli the Bearded" <elijah@workspot.net> gave me the idea that I should |
| 104 | have an Inline one-liner as a signature. |
| 105 | |
| 106 | =back |
| 107 | |
| 108 | =cut -------------------------------------------------------------------------- |
| 109 | |
| 110 | =head1 Meat & Potatoes |
| 111 | |
| 112 | =cut -------------------------------------------------------------------------- |
| 113 | |
| 114 | =head2 Data Types |
| 115 | |
| 116 | =over 4 |
| 117 | |
| 118 | =item Problem |
| 119 | |
| 120 | How do I pass different types of data to and from Inline C functions; |
| 121 | like strings, numbers and integers? |
| 122 | |
| 123 | =item Solution |
| 124 | |
| 125 | # vowels.pl |
| 126 | use Inline C; |
| 127 | |
| 128 | $filename = $ARGV[0]; |
| 129 | die "Usage: perl vowels.pl filename\n" unless -f $filename; |
| 130 | |
| 131 | $text = join '', <>; # slurp input file |
| 132 | $vp = vowel_scan($text); # call our function |
| 133 | $vp = sprintf("%03.1f", $vp * 100); # format for printing |
| 134 | print "The letters in $filename are $vp% vowels.\n"; |
| 135 | |
| 136 | __END__ |
| 137 | __C__ |
| 138 | |
| 139 | /* Find percentage of vowels to letters */ |
| 140 | double vowel_scan(char* str) { |
| 141 | int letters = 0; |
| 142 | int vowels = 0; |
| 143 | int i = 0; |
| 144 | char c; |
| 145 | char normalize = 'a' ^ 'A'; |
| 146 | /* normalize forces lower case in ASCII; upper in EBCDIC */ |
| 147 | char A = normalize | 'a'; |
| 148 | char E = normalize | 'e'; |
| 149 | char I = normalize | 'i'; |
| 150 | char O = normalize | 'o'; |
| 151 | char U = normalize | 'u'; |
| 152 | char Z = normalize | 'z'; |
| 153 | |
| 154 | while(c = str[i++]) { |
| 155 | c |= normalize; |
| 156 | if (c >= A && c <= Z) { |
| 157 | letters++; |
| 158 | if (c == A || c == E || c == I || c == O || c == U) |
| 159 | vowels++; |
| 160 | } |
| 161 | } |
| 162 | |
| 163 | return letters ? ((double) vowels / letters) : 0.0; |
| 164 | } |
| 165 | |
| 166 | =item Discussion |
| 167 | |
| 168 | This script takes a file name from the command line and prints the ratio |
| 169 | of vowels to letters in that file. C<vowels.pl> uses an Inline C |
| 170 | function called C<vowel_scan>, that takes a string argument, and returns |
| 171 | the percentage of vowels as a floating point number between 0 and 1. It |
| 172 | handles upper and lower case letters, and works with ASCII and EBCDIC. |
| 173 | It is also quite fast. |
| 174 | |
| 175 | Running this script produces: |
| 176 | |
| 177 | > perl vowels.pl /usr/dict/words |
| 178 | The letters in /usr/dict/words are 37.5% vowels. |
| 179 | |
| 180 | =item See Also |
| 181 | |
| 182 | The Perl Journal vol #19 has an article about Inline which uses this example. |
| 183 | |
| 184 | =item Credits |
| 185 | |
| 186 | This example was reprinted by permission of The Perl Journal. It was |
| 187 | edited to work with Inline v0.30 and higher. |
| 188 | |
| 189 | =back |
| 190 | |
| 191 | =cut -------------------------------------------------------------------------- |
| 192 | |
| 193 | =head2 Variable Argument Lists |
| 194 | |
| 195 | =over 4 |
| 196 | |
| 197 | =item Problem |
| 198 | |
| 199 | How do I pass a variable-sized list of arguments to an Inline C function? |
| 200 | |
| 201 | =item Solution |
| 202 | |
| 203 | greet(qw(Sarathy Jan Sparky Murray Mike)); |
| 204 | |
| 205 | use Inline C => <<'END_OF_C_CODE'; |
| 206 | |
| 207 | void greet(SV* name1, ...) { |
| 208 | Inline_Stack_Vars; |
| 209 | int i; |
| 210 | |
| 211 | for (i = 0; i < Inline_Stack_Items; i++) |
| 212 | printf("Hello %s!\n", SvPV(Inline_Stack_Item(i), PL_na)); |
| 213 | |
| 214 | Inline_Stack_Void; |
| 215 | } |
| 216 | |
| 217 | END_OF_C_CODE |
| 218 | |
| 219 | |
| 220 | =item Discussion |
| 221 | |
| 222 | This little program greets a group of people, such as my |
| 223 | coworkers. We use the C<C> ellipsis syntax: "C<...>", since the |
| 224 | list can be of any size. |
| 225 | |
| 226 | Since there are no types or names associated with each argument, we |
| 227 | can't expect XS to handle the conversions for us. We'll need to pop them |
| 228 | off the B<Stack> ourselves. Luckily there are two functions (macros) |
| 229 | that make this a very easy task. |
| 230 | |
| 231 | First, we need to begin our function with a "C<Inline_Stack_Vars>" |
| 232 | statement. This defines a few internal variables that we need to access |
| 233 | the B<Stack>. Now we can use "C<Inline_Stack_Items>", which returns an |
| 234 | integer containing the number of arguments passed to us from Perl. |
| 235 | |
| 236 | B<NOTE:> It is important to I<only> use "C<Inline_Stack_>" macros when |
| 237 | there is an ellipsis (C<...>) in the argument list, I<or> the function |
| 238 | has a return type of void. |
| 239 | |
| 240 | Second, we use the C<Inline_Stack_Item(x)> function to access each |
| 241 | argument where "0 <= x < items". |
| 242 | |
| 243 | B<NOTE:> When using a variable length argument list, you have to |
| 244 | specify at least one argument before the ellipsis. (On my compiler, |
| 245 | anyway.) When XS does it's argument checking, it will complain if you |
| 246 | pass in less than the number of I<defined> arguments. Therefore, there |
| 247 | is currently no way to pass an empty list when a variable length list |
| 248 | is expected. |
| 249 | |
| 250 | =item See Also |
| 251 | |
| 252 | =item Credits |
| 253 | |
| 254 | =back |
| 255 | |
| 256 | =cut -------------------------------------------------------------------------- |
| 257 | |
| 258 | =head2 Multiple Return Values |
| 259 | |
| 260 | =over 4 |
| 261 | |
| 262 | =item Problem |
| 263 | |
| 264 | How do I return a list of values from a C function? |
| 265 | |
| 266 | =item Solution |
| 267 | |
| 268 | print map {"$_\n"} get_localtime(time); |
| 269 | |
| 270 | use Inline C => <<'END_OF_C_CODE'; |
| 271 | |
| 272 | #include <time.h> |
| 273 | |
| 274 | void get_localtime(int utc) { |
| 275 | struct tm *ltime = localtime(&utc); |
| 276 | Inline_Stack_Vars; |
| 277 | |
| 278 | Inline_Stack_Reset; |
| 279 | Inline_Stack_Push(sv_2mortal(newSViv(ltime->tm_year))); |
| 280 | Inline_Stack_Push(sv_2mortal(newSViv(ltime->tm_mon))); |
| 281 | Inline_Stack_Push(sv_2mortal(newSViv(ltime->tm_mday))); |
| 282 | Inline_Stack_Push(sv_2mortal(newSViv(ltime->tm_hour))); |
| 283 | Inline_Stack_Push(sv_2mortal(newSViv(ltime->tm_min))); |
| 284 | Inline_Stack_Push(sv_2mortal(newSViv(ltime->tm_sec))); |
| 285 | Inline_Stack_Push(sv_2mortal(newSViv(ltime->tm_isdst))); |
| 286 | Inline_Stack_Done; |
| 287 | } |
| 288 | END_OF_C_CODE |
| 289 | |
| 290 | =item Discussion |
| 291 | |
| 292 | Perl is a language where it is common to return a list of values |
| 293 | from a subroutine call instead of just a single value. C is not such |
| 294 | a language. In order to accomplish this in C we need to manipulate |
| 295 | the Perl call stack by hand. Luckily, Inline provides macros to make |
| 296 | this easy. |
| 297 | |
| 298 | This example calls the system C<localtime>, and returns each of the |
| 299 | parts of the time struct; much like the perl builtin C<localtime()>. On |
| 300 | each stack push, we are creating a new Perl integer (SVIV) and |
| 301 | mortalizing it. The sv_2mortal() call makes sure that the reference |
| 302 | count is set properly. Without it, the program would leak memory. |
| 303 | |
| 304 | NOTE: |
| 305 | The C<#include> statement is not really needed, because Inline |
| 306 | automatically includes the Perl headers which include almost all |
| 307 | standard system calls. |
| 308 | |
| 309 | =item See Also |
| 310 | |
| 311 | For more information on the Inline stack macros, see L<Inline::C>. |
| 312 | |
| 313 | =item Credits |
| 314 | |
| 315 | Richard Anderson <starfire@zipcon.net> contributed the original idea for |
| 316 | this snippet. |
| 317 | |
| 318 | =back |
| 319 | |
| 320 | =cut -------------------------------------------------------------------------- |
| 321 | |
| 322 | =head2 Multiple Return Values (Another Way) |
| 323 | |
| 324 | =over 4 |
| 325 | |
| 326 | =item Problem |
| 327 | |
| 328 | How can I pass back more than one value without using the Perl Stack? |
| 329 | |
| 330 | =item Solution |
| 331 | |
| 332 | use Inline::Files; |
| 333 | use Inline C; |
| 334 | |
| 335 | my ($foo, $bar); |
| 336 | change($foo, $bar); |
| 337 | |
| 338 | print "\$foo = $foo\n"; |
| 339 | print "\$bar = $bar\n"; |
| 340 | |
| 341 | __C__ |
| 342 | |
| 343 | int change(SV* var1, SV* var2) { |
| 344 | sv_setpvn(var1, "Perl Rocks!", 11); |
| 345 | sv_setpvn(var2, "Inline Rules!", 13); |
| 346 | return 1; |
| 347 | } |
| 348 | |
| 349 | =item Discussion |
| 350 | |
| 351 | Most perl function interfaces return values as a list of one or more |
| 352 | scalars. Very few like C<chomp>, will modify an input scalar in place. |
| 353 | On the other hand, in C you do this quite often. Values are passed in by |
| 354 | reference and modified in place by the called function. |
| 355 | |
| 356 | It turns out that we can do that with Inline as well. The secret is to |
| 357 | use a type of 'C<SV*>' for each argument that is to be modified. This |
| 358 | ensures passing by reference, because no typemapping is needed. |
| 359 | |
| 360 | The function can then use the Perl5 API to operate on that argument. |
| 361 | When control returns to Perl, the argument will retain the value set by |
| 362 | the C function. In this example we passed in 2 empty scalars and |
| 363 | assigned values directly to them. |
| 364 | |
| 365 | =item See Also |
| 366 | |
| 367 | =item Credits |
| 368 | |
| 369 | Ned Konz <ned@bike-nomad.com> brought this behavior to my attention. He |
| 370 | also pointed out that he is not the world famous computer cyclist Steve |
| 371 | Roberts (http://www.microship.com), but he is close |
| 372 | (http://bike-nomad.com). Thanks Ned. |
| 373 | |
| 374 | =back |
| 375 | |
| 376 | =cut -------------------------------------------------------------------------- |
| 377 | |
| 378 | =head2 Using Memory |
| 379 | |
| 380 | =over 4 |
| 381 | |
| 382 | =item Problem |
| 383 | |
| 384 | How should I allocate buffers in my Inline C code? |
| 385 | |
| 386 | =item Solution |
| 387 | |
| 388 | print greeting('Ingy'); |
| 389 | |
| 390 | use Inline C => <<'END_OF_C_CODE'; |
| 391 | |
| 392 | SV* greeting(SV* sv_name) { |
| 393 | return (newSVpvf("Hello %s!\n", SvPV(sv_name, PL_na))); |
| 394 | } |
| 395 | |
| 396 | END_OF_C_CODE |
| 397 | |
| 398 | =item Discussion |
| 399 | |
| 400 | In this example we will return the greeting to the caller, rather than |
| 401 | printing it. This would seem mighty easy, except for the fact that we |
| 402 | need to allocate a small buffer to create the greeting. |
| 403 | |
| 404 | I would urge you to stay away from C<malloc>ing your own buffer. Just |
| 405 | use Perl's built in memory management. In other words, just create a new |
| 406 | Perl string scalar. The function C<newSVpv> does just that. And |
| 407 | C<newSVpvf> includes C<sprintf> functionality. |
| 408 | |
| 409 | The other problem is getting rid of this new scalar. How will the ref |
| 410 | count get decremented after we pass the scalar back? Perl also provides |
| 411 | a function called C<sv_2mortal>. Mortal variables die when the context |
| 412 | goes out of scope. In other words, Perl will wait until the new scalar |
| 413 | gets passed back and then decrement the ref count for you, thereby |
| 414 | making it eligible for garbage collection. See C<perldoc perlguts>. |
| 415 | |
| 416 | In this example the C<sv_2mortal> call gets done under the hood by XS, |
| 417 | because we declared the return type to be C<SV*>. |
| 418 | |
| 419 | To view the generated XS code, run the command "C<perl |
| 420 | -MInline=INFO,FORCE,NOCLEAN example004.pl>". This will leave the build |
| 421 | directory intact and tell you where to find it. |
| 422 | |
| 423 | =item See Also |
| 424 | |
| 425 | =item Credits |
| 426 | |
| 427 | =back |
| 428 | |
| 429 | =cut -------------------------------------------------------------------------- |
| 430 | |
| 431 | =head1 Fast Food |
| 432 | |
| 433 | =cut -------------------------------------------------------------------------- |
| 434 | |
| 435 | =head2 Inline CGI |
| 436 | |
| 437 | =over 4 |
| 438 | |
| 439 | =item Problem |
| 440 | |
| 441 | How do I use Inline securely in a CGI environment? |
| 442 | |
| 443 | =item Solution |
| 444 | |
| 445 | #!/usr/bin/perl |
| 446 | |
| 447 | use CGI qw(:standard); |
| 448 | use Inline (Config => |
| 449 | DIRECTORY => '/usr/local/apache/Inline', |
| 450 | ); |
| 451 | |
| 452 | print (header, |
| 453 | start_html('Inline CGI Example'), |
| 454 | h1(JAxH('Inline')), |
| 455 | end_html |
| 456 | ); |
| 457 | |
| 458 | use Inline C => <<END; |
| 459 | SV* JAxH(char* x) { |
| 460 | return newSVpvf("Just Another %s Hacker", x); |
| 461 | } |
| 462 | END |
| 463 | |
| 464 | =item Discussion |
| 465 | |
| 466 | The problem with running Inline code from a CGI script is that Inline |
| 467 | B<writes> to a build area on your disk whenever it compiles code. Most |
| 468 | CGI scripts don't (and shouldn't) be able to create a directory and |
| 469 | write into it. |
| 470 | |
| 471 | The solution is to explicitly tell Inline which directory to use with |
| 472 | the 'use Inline Config => DIRECTORY => ...' line. Then you need to give |
| 473 | write access to that directory from the web server (CGI script). |
| 474 | |
| 475 | If you see this as a security hole, then there is another option. |
| 476 | Give write access to yourself, but read-only access to the CGI |
| 477 | script. Then run the script once by hand (from the command line). |
| 478 | This will cause Inline to precompile the C code. That way the CGI |
| 479 | will only need read access to the build directory (to load in the |
| 480 | shared library from there). |
| 481 | |
| 482 | Just remember that whenever you change the C code, you need to |
| 483 | precompile it again. |
| 484 | |
| 485 | =item See Also |
| 486 | |
| 487 | See L<CGI> for more information on using the C<CGI.pm> module. |
| 488 | |
| 489 | =item Credits |
| 490 | |
| 491 | =back |
| 492 | |
| 493 | =cut -------------------------------------------------------------------------- |
| 494 | |
| 495 | =head2 mod_perl |
| 496 | |
| 497 | =over 4 |
| 498 | |
| 499 | =item Problem |
| 500 | |
| 501 | How do I use Inline with mod_perl? |
| 502 | |
| 503 | =item Solution |
| 504 | |
| 505 | package Factorial; |
| 506 | use strict; |
| 507 | use Inline Config => |
| 508 | DIRECTORY => '/usr/local/apache/Inline', |
| 509 | ENABLE => 'UNTAINT'; |
| 510 | use Inline 'C'; |
| 511 | Inline->init; |
| 512 | |
| 513 | sub handler { |
| 514 | my $r = shift; |
| 515 | $r->send_http_header('text/plain'); |
| 516 | printf "%3d! = %10d\n", $_, factorial($_) for 1..100; |
| 517 | return Apache::Constants::OK; |
| 518 | } |
| 519 | |
| 520 | 1; |
| 521 | __DATA__ |
| 522 | __C__ |
| 523 | double factorial(double x) { |
| 524 | if (x < 2) return 1; |
| 525 | return x * factorial(x - 1) |
| 526 | } |
| 527 | |
| 528 | =item Discussion |
| 529 | |
| 530 | This is a fully functional mod_perl handler that prints out the |
| 531 | factorial values for the numbers 1 to 100. Since we are using Inline |
| 532 | under mod_perl, there are a few considerations to , um, consider. |
| 533 | |
| 534 | First, mod_perl handlers are usually run with C<-T> taint detection. |
| 535 | Therefore, we need to enable the UNTAINT option. The next thing to deal |
| 536 | with is the fact that this handler will most likely be loaded after |
| 537 | Perl's compile time. Since we are using the DATA section, we need to |
| 538 | use the special C<init()> call. And of course we need to specify a |
| 539 | DIRECTORY that mod_perl can compile into. I<See the above CGI example |
| 540 | for more info.> |
| 541 | |
| 542 | Other than that, this is a pretty straightforward mod_perl handler, |
| 543 | tuned for even more speed! |
| 544 | |
| 545 | =item See Also |
| 546 | |
| 547 | See Stas Bekman's upcoming O'Reilly book on mod_perl to which this |
| 548 | example was contributed. |
| 549 | |
| 550 | =item Credits |
| 551 | |
| 552 | =back |
| 553 | |
| 554 | =cut -------------------------------------------------------------------------- |
| 555 | |
| 556 | =head2 Object Oriented Inline |
| 557 | |
| 558 | =over 4 |
| 559 | |
| 560 | =item Problem |
| 561 | |
| 562 | How do I implement Object Oriented programming in Perl using C objects? |
| 563 | |
| 564 | =item Solution |
| 565 | |
| 566 | my $obj1 = Soldier->new('Benjamin', 'Private', 11111); |
| 567 | my $obj2 = Soldier->new('Sanders', 'Colonel', 22222); |
| 568 | my $obj3 = Soldier->new('Matt', 'Sergeant', 33333); |
| 569 | |
| 570 | for my $obj ($obj1, $obj2, $obj3) { |
| 571 | print ($obj->get_serial, ") ", |
| 572 | $obj->get_name, " is a ", |
| 573 | $obj->get_rank, "\n"); |
| 574 | } |
| 575 | |
| 576 | #--------------------------------------------------------- |
| 577 | |
| 578 | package Soldier; |
| 579 | |
| 580 | use Inline C => <<'END'; |
| 581 | |
| 582 | typedef struct { |
| 583 | char* name; |
| 584 | char* rank; |
| 585 | long serial; |
| 586 | } Soldier; |
| 587 | |
| 588 | SV* new(char* class, char* name, char* rank, long serial) { |
| 589 | Soldier* soldier = malloc(sizeof(Soldier)); |
| 590 | SV* obj_ref = newSViv(0); |
| 591 | SV* obj = newSVrv(obj_ref, class); |
| 592 | |
| 593 | soldier->name = strdup(name); |
| 594 | soldier->rank = strdup(rank); |
| 595 | soldier->serial = serial; |
| 596 | |
| 597 | sv_setiv(obj, (IV)soldier); |
| 598 | SvREADONLY_on(obj); |
| 599 | return obj_ref; |
| 600 | } |
| 601 | |
| 602 | char* get_name(SV* obj) { |
| 603 | return ((Soldier*)SvIV(SvRV(obj)))->name; |
| 604 | } |
| 605 | |
| 606 | char* get_rank(SV* obj) { |
| 607 | return ((Soldier*)SvIV(SvRV(obj)))->rank; |
| 608 | } |
| 609 | |
| 610 | long get_serial(SV* obj) { |
| 611 | return ((Soldier*)SvIV(SvRV(obj)))->serial; |
| 612 | } |
| 613 | |
| 614 | void DESTROY(SV* obj) { |
| 615 | Soldier* soldier = (Soldier*)SvIV(SvRV(obj)); |
| 616 | free(soldier->name); |
| 617 | free(soldier->rank); |
| 618 | free(soldier); |
| 619 | } |
| 620 | END |
| 621 | |
| 622 | =item Discussion |
| 623 | |
| 624 | Damian Conway has given us myriad ways of implementing OOP in Perl. This |
| 625 | is one he might not have thought of. |
| 626 | |
| 627 | The interesting thing about this example is that it uses Perl for all |
| 628 | the OO bindings while using C for the attributes and methods. |
| 629 | |
| 630 | If you examine the Perl code everything looks exactly like a regular OO |
| 631 | example. There is a C<new> method and several accessor methods. The |
| 632 | familiar 'arrow syntax' is used to invoke them. |
| 633 | |
| 634 | In the class definition (second part) the Perl C<package> statement is |
| 635 | used to name the object class or namespace. But that's where the |
| 636 | similarities end Inline takes over. |
| 637 | |
| 638 | The idea is that we call a C subroutine called C<new()> which returns a |
| 639 | blessed scalar. The scalar contains a readonly integer which is a C |
| 640 | pointer to a Soldier struct. This is our object. |
| 641 | |
| 642 | The C<new()> function needs to malloc the memory for the struct and then |
| 643 | copy the initial values into it using C<strdup()>. This also allocates |
| 644 | more memory (which we have to keep track of). |
| 645 | |
| 646 | The accessor methods are pretty straightforward. They return the current |
| 647 | value of their attribute. |
| 648 | |
| 649 | The last method C<DESTROY()> is called automatically by Perl whenever an |
| 650 | object goes out of scope. This is where we can free all the memory used |
| 651 | by the object. |
| 652 | |
| 653 | That's it. It's a very simplistic example. It doesn't show off any |
| 654 | advanced OO features, but it is pretty cool to see how easy the |
| 655 | implementation can be. The important Perl call is C<newSVrv()> which |
| 656 | creates a blessed scalar. |
| 657 | |
| 658 | =item See Also |
| 659 | |
| 660 | Read "Object Oriented Perl" by Damian Conway, for more useful ways of |
| 661 | doing OOP in Perl. |
| 662 | |
| 663 | You can learn more Perl calls in L<perlapi>. If you don't have Perl |
| 664 | 5.6.0 or higher, visit http://www.perldoc.com/perl5.6/pod/perlapi.html |
| 665 | |
| 666 | =item Credits |
| 667 | |
| 668 | =back |
| 669 | |
| 670 | =cut -------------------------------------------------------------------------- |
| 671 | |
| 672 | =head1 The Main Course |
| 673 | |
| 674 | =cut -------------------------------------------------------------------------- |
| 675 | |
| 676 | =head2 Exposing Shared Libraries |
| 677 | |
| 678 | =over 4 |
| 679 | |
| 680 | =item Problem |
| 681 | |
| 682 | You have this great C library and you want to be able to access parts of |
| 683 | it with Perl. |
| 684 | |
| 685 | =item Solution |
| 686 | |
| 687 | print get('http://www.axkit.org'); |
| 688 | |
| 689 | use Inline C => Config => |
| 690 | LIBS => '-lghttp'; |
| 691 | use Inline C => <<'END_OF_C_CODE'; |
| 692 | |
| 693 | #include <ghttp.h> |
| 694 | |
| 695 | char *get(SV* uri) { |
| 696 | SV* buffer; |
| 697 | ghttp_request* request; |
| 698 | |
| 699 | buffer = NEWSV(0,0); |
| 700 | request = ghttp_request_new(); |
| 701 | ghttp_set_uri(request, SvPV(uri, PL_na)); |
| 702 | |
| 703 | ghttp_set_header(request, http_hdr_Connection, "close"); |
| 704 | |
| 705 | ghttp_prepare(request); |
| 706 | ghttp_process(request); |
| 707 | |
| 708 | sv_catpv(buffer, ghttp_get_body(request)); |
| 709 | |
| 710 | ghttp_request_destroy(request); |
| 711 | |
| 712 | return SvPV(buffer, PL_na); |
| 713 | } |
| 714 | |
| 715 | END_OF_C_CODE |
| 716 | |
| 717 | =item Discussion |
| 718 | |
| 719 | This example fetches and prints the HTML from http://www.axkit.org |
| 720 | It requires the GNOME http libraries. http://www.gnome.org |
| 721 | |
| 722 | One of the most common questions I get is "How can I use Inline to make |
| 723 | use of some shared library?". Although it has always been possible to do |
| 724 | so, the configuration was ugly, and there were no specific examples. |
| 725 | |
| 726 | With version 0.30 and higher, you can specify the use of shared |
| 727 | libraries easily with something like this: |
| 728 | |
| 729 | use Inline C => Config => LIBS => '-lghttp'; |
| 730 | use Inline C => "code ..."; |
| 731 | |
| 732 | or |
| 733 | |
| 734 | use Inline C => "code ...", LIBS => '-lghttp'; |
| 735 | |
| 736 | To specify a specific library path, use: |
| 737 | |
| 738 | use Inline C => "code ...", LIBS => '-L/your/lib/path -lyourlib'; |
| 739 | |
| 740 | To specify an include path use: |
| 741 | |
| 742 | use Inline C => "code ...", |
| 743 | LIBS => '-lghttp', |
| 744 | INC => '-I/your/inc/path'; |
| 745 | |
| 746 | =item See Also |
| 747 | |
| 748 | The C<LIBS> and C<INC> configuration options are formatted and passed |
| 749 | into MakeMaker. For more info see L<ExtUtils::MakeMaker>. For more |
| 750 | options see L<Inline::C>. |
| 751 | |
| 752 | =item Credits |
| 753 | |
| 754 | This code was written by Matt Sergeant <matt@sergeant.org>, author of |
| 755 | many CPAN modules. The configuration syntax has been modified for use |
| 756 | with Inline v0.30. |
| 757 | |
| 758 | =back |
| 759 | |
| 760 | =head2 Automatic Function Wrappers |
| 761 | |
| 762 | =over 4 |
| 763 | |
| 764 | =item Problem |
| 765 | |
| 766 | You have some functions in a C library that you want to access from Perl |
| 767 | exactly as you would from C. |
| 768 | |
| 769 | =item Solution |
| 770 | |
| 771 | The error function C<erf()> is probably defined in your standard math |
| 772 | library. Annoyingly, Perl does not let you access it. To print out a |
| 773 | small table of its values, just say: |
| 774 | |
| 775 | perl -le 'use Inline C => q{ double erf(double); }, ENABLE => "AUTOWRAP"; print "$_ @{[erf($_)]}" for (0..10)' |
| 776 | |
| 777 | The excellent C<Term::ReadLine::Gnu> implements Term::ReadLine using the |
| 778 | GNU ReadLine library. Here is an easy way to access just C<readline()> |
| 779 | from that library: |
| 780 | |
| 781 | package MyTerm; |
| 782 | |
| 783 | use Inline C => Config => |
| 784 | ENABLE => AUTOWRAP => |
| 785 | LIBS => "-lreadline -lncurses -lterminfo -ltermcap "; |
| 786 | use Inline C => q{ char * readline(char *); }; |
| 787 | |
| 788 | package main; |
| 789 | my $x = MyTerm::readline("xyz: "); |
| 790 | |
| 791 | Note however that it fails to C<free()> the memory returned by readline, |
| 792 | and that C<Term::ReadLine::Gnu> offers a much richer interface. |
| 793 | |
| 794 | =item Discussion |
| 795 | |
| 796 | We access existing functions by merely showing Inline their |
| 797 | declarations, rather than a full definition. Of course the function |
| 798 | declared must exist, either in a library already linked to Perl or in a |
| 799 | library specified using the C<LIBS> option. |
| 800 | |
| 801 | The first example wraps a function from the standard math library, so |
| 802 | Inline requires no additional C<LIBS> directive. The second uses the |
| 803 | Config option to specify the libraries that contain the actual |
| 804 | compiled C code. |
| 805 | |
| 806 | This behavior is always disabled by default. You must enable the |
| 807 | C<AUTOWRAP> option to make it work. |
| 808 | |
| 809 | =item See Also |
| 810 | |
| 811 | C<readline>, C<Term::ReadLine::Gnu> |
| 812 | |
| 813 | =item Credits |
| 814 | |
| 815 | GNU ReadLine was written by Brian Fox <bfox@ai.mit.edu> and Chet Ramey |
| 816 | <chet@ins.cwru.edu>. Term::ReadLine::Gnu was written by Hiroo Hayashi |
| 817 | <hiroo.hayashi@computer.org>. Both are far richer than the slim |
| 818 | interface given here! |
| 819 | |
| 820 | The idea of producing wrapper code given only a function declaration is |
| 821 | taken from Swig by David M. Beazley <beazley@cs.uchicago.edu>. |
| 822 | |
| 823 | Ingy's inline editorial insight: |
| 824 | |
| 825 | This entire entry was contributed by Ariel Scolnicov |
| 826 | <ariels@compugen.co.il>. Ariel also first suggested the idea for Inline |
| 827 | to support function declaration processing. |
| 828 | |
| 829 | =back |
| 830 | |
| 831 | =cut -------------------------------------------------------------------------- |
| 832 | |
| 833 | =head2 Complex Data |
| 834 | |
| 835 | =over 4 |
| 836 | |
| 837 | =item Problem |
| 838 | |
| 839 | How do I deal with complex data types like hashes in Inline C? |
| 840 | |
| 841 | =item Solution |
| 842 | |
| 843 | use Inline C => <<'END_OF_C_CODE'; |
| 844 | |
| 845 | void dump_hash(SV* hash_ref) { |
| 846 | HV* hash; |
| 847 | HE* hash_entry; |
| 848 | int num_keys, i; |
| 849 | SV* sv_key; |
| 850 | SV* sv_val; |
| 851 | |
| 852 | if (! SvROK(hash_ref)) |
| 853 | croak("hash_ref is not a reference"); |
| 854 | |
| 855 | hash = (HV*)SvRV(hash_ref); |
| 856 | num_keys = hv_iterinit(hash); |
| 857 | for (i = 0; i < num_keys; i++) { |
| 858 | hash_entry = hv_iternext(hash); |
| 859 | sv_key = hv_iterkeysv(hash_entry); |
| 860 | sv_val = hv_iterval(hash, hash_entry); |
| 861 | printf("%s => %s\n", SvPV(sv_key, PL_na), SvPV(sv_val, PL_na)); |
| 862 | } |
| 863 | return; |
| 864 | } |
| 865 | |
| 866 | END_OF_C_CODE |
| 867 | |
| 868 | my %hash = ( |
| 869 | Author => "Brian Ingerson", |
| 870 | Nickname => "INGY", |
| 871 | Module => "Inline.pm", |
| 872 | Version => "0.30", |
| 873 | Language => "C", |
| 874 | ); |
| 875 | |
| 876 | dump_hash(\%hash); |
| 877 | |
| 878 | =item Discussion |
| 879 | |
| 880 | The world is not made of scalars alone, although they are definitely |
| 881 | the easiest creatures to deal with, when doing Inline stuff. |
| 882 | Sometimes we need to deal with arrays, hashes, and code references, |
| 883 | among other things. |
| 884 | |
| 885 | Since Perl subroutine calls only pass scalars as arguments, we'll |
| 886 | need to use the argument type C<SV*> and pass references to more |
| 887 | complex types. |
| 888 | |
| 889 | The above program dumps the key/value pairs of a hash. To figure it out, |
| 890 | just curl up with L<perlapi> for a couple hours. Actually, its fairly |
| 891 | straight forward once you are familiar with the calls. |
| 892 | |
| 893 | Note the C<croak> function call. This is the proper way to die from your |
| 894 | C extensions. |
| 895 | |
| 896 | =item See Also |
| 897 | |
| 898 | See L<perlapi> for information about the Perl5 internal API. |
| 899 | |
| 900 | =item Credits |
| 901 | |
| 902 | =back |
| 903 | |
| 904 | =cut -------------------------------------------------------------------------- |
| 905 | |
| 906 | =head2 Hash of Lists |
| 907 | |
| 908 | =over 4 |
| 909 | |
| 910 | =item Problem |
| 911 | |
| 912 | How do I create a Hash of Lists from C? |
| 913 | |
| 914 | =item Solution |
| 915 | |
| 916 | use Inline C; |
| 917 | use Data::Dumper; |
| 918 | |
| 919 | $hash_ref = load_data("./cartoon.txt"); |
| 920 | print Dumper $hash_ref; |
| 921 | |
| 922 | __END__ |
| 923 | __C__ |
| 924 | |
| 925 | static int next_word(char**, char*); |
| 926 | |
| 927 | SV* load_data(char* file_name) { |
| 928 | char buffer[100], word[100], * pos; |
| 929 | AV* array; |
| 930 | HV* hash = newHV(); |
| 931 | FILE* fh = fopen(file_name, "r"); |
| 932 | |
| 933 | while (fgets(pos = buffer, sizeof(buffer), fh)) { |
| 934 | if (next_word(&pos, word)) { |
| 935 | hv_store(hash, word, strlen(word), |
| 936 | newRV_noinc((SV*)array = newAV()), 0); |
| 937 | while (next_word(&pos, word)) |
| 938 | av_push(array, newSVpvf("%s", word)); |
| 939 | } |
| 940 | } |
| 941 | fclose(fh); |
| 942 | return newRV_noinc((SV*) hash); |
| 943 | } |
| 944 | |
| 945 | static int next_word(char** text_ptr, char* word) { |
| 946 | char* text = *text_ptr; |
| 947 | while(*text != '\0' && |
| 948 | *text <= ' ') |
| 949 | text++; |
| 950 | if (*text <= ' ') |
| 951 | return 0; |
| 952 | while(*text != '\0' && |
| 953 | *text > ' ') { |
| 954 | *word++ = *text++; |
| 955 | } |
| 956 | *word = '\0'; |
| 957 | *text_ptr = text; |
| 958 | return 1; |
| 959 | } |
| 960 | |
| 961 | =item Discussion |
| 962 | |
| 963 | This is one of the larger recipes. But when you consider the number of |
| 964 | calories it has, it's not so bad. The function C<load_data> takes the |
| 965 | name of a file as it's input. The file C<cartoon.text> might look like: |
| 966 | |
| 967 | flintstones fred barney |
| 968 | jetsons george jane elroy |
| 969 | simpsons homer marge bart |
| 970 | |
| 971 | The function will read the file, parsing each line into words. Then it |
| 972 | will create a new hash, whereby the first word in a line becomes a hash |
| 973 | key and the remaining words are put into an array whose reference |
| 974 | becomes the hash value. The output looks like this: |
| 975 | |
| 976 | $VAR1 = { |
| 977 | 'flintstones' => [ |
| 978 | 'fred', |
| 979 | 'barney' |
| 980 | ], |
| 981 | 'simpsons' => [ |
| 982 | 'homer', |
| 983 | 'marge', |
| 984 | 'bart' |
| 985 | ], |
| 986 | 'jetsons' => [ |
| 987 | 'george', |
| 988 | 'jane', |
| 989 | 'elroy' |
| 990 | ] |
| 991 | }; |
| 992 | |
| 993 | =item See Also |
| 994 | |
| 995 | See L<perlapi> for information about the Perl5 internal API. |
| 996 | |
| 997 | =item Credits |
| 998 | |
| 999 | Al Danial <alnd@pacbell.net> requested a solution to this on |
| 1000 | comp.lang.perl.misc. He borrowed the idea from the "Hash of Lists" |
| 1001 | example in the Camel book. |
| 1002 | |
| 1003 | =back |
| 1004 | |
| 1005 | =cut -------------------------------------------------------------------------- |
| 1006 | |
| 1007 | =head1 Just Desserts |
| 1008 | |
| 1009 | =cut -------------------------------------------------------------------------- |
| 1010 | |
| 1011 | =head2 Win32 |
| 1012 | |
| 1013 | =over 4 |
| 1014 | |
| 1015 | =item Problem |
| 1016 | |
| 1017 | How do I access Win32 DLL-s using Inline? |
| 1018 | |
| 1019 | =item Solution |
| 1020 | |
| 1021 | use Inline C => DATA => |
| 1022 | LIBS => '-luser32'; |
| 1023 | |
| 1024 | $text = "@ARGV" || 'Inline.pm works with MSWin32. Scary...'; |
| 1025 | |
| 1026 | WinBox('Inline Text Box', $text); |
| 1027 | |
| 1028 | __END__ |
| 1029 | __C__ |
| 1030 | |
| 1031 | #include <windows.h> |
| 1032 | |
| 1033 | int WinBox(char* Caption, char* Text) { |
| 1034 | return MessageBoxA(0, Text, Caption, 0); |
| 1035 | } |
| 1036 | |
| 1037 | =item Discussion |
| 1038 | |
| 1039 | This example runs on MS Windows. It makes a text box appear on the |
| 1040 | screen which contains a message of your choice. |
| 1041 | |
| 1042 | The important thing is that its proof that you can use Inline to |
| 1043 | interact with Windows DLL-s. Very scary indeed. 8-o |
| 1044 | |
| 1045 | To use Inline on Windows with ActivePerl ( http://www.ActiveState.com ) |
| 1046 | you'll need MS Visual Studio. You can also use the Cygwin environment, |
| 1047 | available at http://www.cygwin.com . |
| 1048 | |
| 1049 | =item See Also |
| 1050 | |
| 1051 | See L<Inline-Support> for more info on MSWin32 programming with Inline. |
| 1052 | |
| 1053 | =item Credits |
| 1054 | |
| 1055 | This example was adapted from some sample code written by Garrett Goebel |
| 1056 | <garrett@scriptpro.com> |
| 1057 | |
| 1058 | =back |
| 1059 | |
| 1060 | =cut -------------------------------------------------------------------------- |
| 1061 | |
| 1062 | =head2 Embedding Perl in C |
| 1063 | |
| 1064 | =over 4 |
| 1065 | |
| 1066 | =item Problem |
| 1067 | |
| 1068 | How do I use Perl from a regular C program? |
| 1069 | |
| 1070 | =item Solution |
| 1071 | |
| 1072 | #!/usr/bin/cpr |
| 1073 | |
| 1074 | int main(void) { |
| 1075 | |
| 1076 | printf("Using Perl version %s from a C program!\n\n", |
| 1077 | CPR_eval("use Config; $Config{version};")); |
| 1078 | |
| 1079 | CPR_eval("use Data::Dumper;"); |
| 1080 | CPR_eval("print Dumper \\%INC;"); |
| 1081 | |
| 1082 | return 0; |
| 1083 | |
| 1084 | } |
| 1085 | |
| 1086 | =item Discussion |
| 1087 | |
| 1088 | By using CPR. (C Perl Run) |
| 1089 | |
| 1090 | This example uses another Inline module, C<Inline::CPR>, available |
| 1091 | separately on CPAN. When you install this module it also installs a |
| 1092 | binary interpreter called C</usr/bin/cpr>. (The path may be different on |
| 1093 | your system) |
| 1094 | |
| 1095 | When you feed a C program to the CPR interpreter, it automatically |
| 1096 | compiles and runs your code using Inline. This gives you full access to |
| 1097 | the Perl internals. CPR also provides a set of easy to use C macros for |
| 1098 | calling Perl internals. |
| 1099 | |
| 1100 | This means that you can effectively "run" C source code by putting a CPR |
| 1101 | hashbang as the first line of your C program. |
| 1102 | |
| 1103 | =item See Also |
| 1104 | |
| 1105 | See L<Inline::CPR> for more information on using CPR. |
| 1106 | |
| 1107 | C<Inline::CPR> can be obtained from |
| 1108 | http://search.cpan.org/search?dist=Inline-CPR |
| 1109 | |
| 1110 | =item Credits |
| 1111 | |
| 1112 | Randal Schwartz <merlyn@stonehenge.com>, Randolph Bentson |
| 1113 | <bentson@grieg.holmsjoen.com>, Richard Anderson <starfire@zipcon.net>, |
| 1114 | and Tim Maher <tim@consultix-inc.com> helped me figure out how to write |
| 1115 | a program that would work as a hashbang. |
| 1116 | |
| 1117 | =back |
| 1118 | |
| 1119 | =cut -------------------------------------------------------------------------- |
| 1120 | |
| 1121 | =head1 Entertaining Guests |
| 1122 | |
| 1123 | As of version 0.30, Inline has the ability to work in cooperation with |
| 1124 | other modules that want to expose a C API of their own. The general |
| 1125 | syntax for doing this is: |
| 1126 | |
| 1127 | use Inline with => 'Module'; |
| 1128 | use Inline C => ... ; |
| 1129 | |
| 1130 | This tells C<Module> to pass configuration options to Inline. Options |
| 1131 | like typemaps, include paths, and external libraries, are all resolved |
| 1132 | automatically so you can just concentrate on writing the functions. |
| 1133 | |
| 1134 | =cut -------------------------------------------------------------------------- |
| 1135 | |
| 1136 | =head2 Event handling with Event.pm |
| 1137 | |
| 1138 | =over 4 |
| 1139 | |
| 1140 | =item Problem |
| 1141 | |
| 1142 | You need to write a C callback for the C<Event.pm> module. Can this be |
| 1143 | done more easily with Inline? |
| 1144 | |
| 1145 | =item Solution |
| 1146 | |
| 1147 | use Inline with => 'Event'; |
| 1148 | |
| 1149 | Event->timer(desc => 'Timer #1', |
| 1150 | interval => 2, |
| 1151 | cb => \&my_callback, |
| 1152 | ); |
| 1153 | |
| 1154 | Event->timer(desc => 'Timer #2', |
| 1155 | interval => 3, |
| 1156 | cb => \&my_callback, |
| 1157 | ); |
| 1158 | |
| 1159 | print "Starting...\n"; |
| 1160 | Event::loop; |
| 1161 | |
| 1162 | use Inline C => <<'END'; |
| 1163 | void my_callback(pe_event* event) { |
| 1164 | pe_timer * watcher = event->up; |
| 1165 | |
| 1166 | printf("%s\n\tEvent priority = %d\n\tWatcher priority = %d\n\n", |
| 1167 | SvPVX(watcher->base.desc), |
| 1168 | event->prio, |
| 1169 | watcher->base.prio |
| 1170 | ); |
| 1171 | } |
| 1172 | END |
| 1173 | |
| 1174 | =item Discussion |
| 1175 | |
| 1176 | The first line tells Inline to load the C<Event.pm> module. Inline then |
| 1177 | queries C<Event> for configuration information. It gets the name and |
| 1178 | location of Event's header files, typemaps and shared objects. The |
| 1179 | parameters that C<Event> returns look like: |
| 1180 | |
| 1181 | INC => "-I $path/Event", |
| 1182 | TYPEMAPS => "$path/Event/typemap", |
| 1183 | MYEXTLIB => "$path/auto/Event/Event.$so", |
| 1184 | AUTO_INCLUDE => '#include "EventAPI.h"', |
| 1185 | BOOT => 'I_EVENT_API("Inline");', |
| 1186 | |
| 1187 | Doing all of this automatically allows you, the programmer, to simply |
| 1188 | write a function that receives a pointer of type C<'pe_event*'>. This |
| 1189 | gives you access to the C<Event> structure that was passed to you. |
| 1190 | |
| 1191 | In this example, I simply print values out of the structure. The Perl |
| 1192 | code defines 2 timer events which each invoke the same callback. The |
| 1193 | first one, every two seconds, and the second one, every three seconds. |
| 1194 | |
| 1195 | As of this writing, C<Event.pm> is the only CPAN module that works in |
| 1196 | cooperation with Inline. |
| 1197 | |
| 1198 | =item See Also |
| 1199 | |
| 1200 | Read the C<Event.pm> documentation for more information. It contains a |
| 1201 | tutorial showing several examples of using Inline with C<Event>. |
| 1202 | |
| 1203 | =item Credits |
| 1204 | |
| 1205 | Jochen Stenzel <perl@jochen-stenzel.de> originally came up with the idea |
| 1206 | of mixing Inline and C<Event>. He also authored the C<Event> tutorial. |
| 1207 | |
| 1208 | Joshua Pritikin <joshua.pritikin@db.com> is the author of C<Event.pm>. |
| 1209 | |
| 1210 | =back |
| 1211 | |
| 1212 | =cut -------------------------------------------------------------------------- |
| 1213 | |
| 1214 | =head1 Food for Thought |
| 1215 | |
| 1216 | =cut -------------------------------------------------------------------------- |
| 1217 | |
| 1218 | =head2 Calling C from both Perl and C |
| 1219 | |
| 1220 | =over 4 |
| 1221 | |
| 1222 | =item Problem |
| 1223 | |
| 1224 | I'd like to be able to call the same C function from both Perl and C. |
| 1225 | Also I like to define a C function that B<doesn't> get bound to Perl. |
| 1226 | How do I do that? |
| 1227 | |
| 1228 | =item Solution |
| 1229 | |
| 1230 | print "9 + 5 = ", add(9, 5), "\n"; |
| 1231 | print "SQRT(9^2 + 5^2) = ", pyth(9, 5), "\n"; |
| 1232 | print "9 * 5 = ", mult(9, 5), "\n"; |
| 1233 | |
| 1234 | use Inline C => <<'END_C'; |
| 1235 | int add(int x, int y) { |
| 1236 | return x + y; |
| 1237 | } |
| 1238 | static int mult(int x, int y) { |
| 1239 | return x * y; |
| 1240 | } |
| 1241 | double pyth(int x, int y) { |
| 1242 | return sqrt(add(mult(x, x), mult(y, y))); |
| 1243 | } |
| 1244 | END_C |
| 1245 | |
| 1246 | =item Discussion |
| 1247 | |
| 1248 | The program produces: |
| 1249 | |
| 1250 | 9 + 5 = 14 |
| 1251 | SQRT(9^2 + 5^2) = 10.295630140987 |
| 1252 | Can't locate auto/main/mult.al in @INC ... |
| 1253 | |
| 1254 | Every Inline function that is bound to Perl is also callable by C. You |
| 1255 | don't have to do anything special. Inline arranges it so that all the |
| 1256 | typemap code gets done by XS and is out of sight. By the time the C |
| 1257 | function receives control, everything has been converted from Perl to C. |
| 1258 | |
| 1259 | Of course if your function manipulates the Perl Stack, you |
| 1260 | probably don't want to call it from C (unless you I<really> know |
| 1261 | what you're doing). |
| 1262 | |
| 1263 | If you declare a function as C<static>, Inline won't bind it to Perl. |
| 1264 | That's why we were able to call C<mult()> from C but the call failed |
| 1265 | from Perl. |
| 1266 | |
| 1267 | =item See Also |
| 1268 | |
| 1269 | =item Credits |
| 1270 | |
| 1271 | =back |
| 1272 | |
| 1273 | =cut -------------------------------------------------------------------------- |
| 1274 | |
| 1275 | =head2 Calling Perl from C |
| 1276 | |
| 1277 | =over 4 |
| 1278 | |
| 1279 | =item Problem |
| 1280 | |
| 1281 | So now that I can call C from Perl, how do I call a Perl subroutine from |
| 1282 | an Inline C function. |
| 1283 | |
| 1284 | =item Solution |
| 1285 | |
| 1286 | use Inline C; |
| 1287 | |
| 1288 | c_func_1('This is the first line'); |
| 1289 | c_func_2('This is the second line'); |
| 1290 | |
| 1291 | sub perl_sub_1 { |
| 1292 | print map "$_\n", @_; |
| 1293 | } |
| 1294 | |
| 1295 | __DATA__ |
| 1296 | __C__ |
| 1297 | |
| 1298 | void c_func_1(SV* text) { |
| 1299 | c_func_2(text); |
| 1300 | } |
| 1301 | |
| 1302 | void c_func_2(SV* text) { |
| 1303 | Inline_Stack_Vars; |
| 1304 | Inline_Stack_Push(newSVpvf("Plus an extra line")); |
| 1305 | Inline_Stack_Done; |
| 1306 | perl_call_pv("main::perl_sub_1", 0); |
| 1307 | Inline_Stack_Void; |
| 1308 | } |
| 1309 | |
| 1310 | |
| 1311 | =item Discussion |
| 1312 | |
| 1313 | Actually, this program demonstrates calling a C function which calls |
| 1314 | another C function which in turn calls a Perl subroutine. |
| 1315 | |
| 1316 | The nice thing about Inline C functions is that you can call them from |
| 1317 | both Perl-space B<and> C-space. That's because Inline creates a wrapper |
| 1318 | function around each C function. When you use Perl to call C you're |
| 1319 | actually calling that function's wrapper. The wrapper handles |
| 1320 | typemapping and Stack management, and then calls your C function. |
| 1321 | |
| 1322 | The first time we call C<c_func_1> which calls C<c_func_2>. The second |
| 1323 | time we call C<c_func_2> directly. C<c_func_2> calls the Perl subroutine |
| 1324 | (C<perl_sub_1>) using the internal C<perl_call_pv> function. It has to |
| 1325 | put arguments on the stack by hand. Since there is already one argument |
| 1326 | on the stack when we enter the function, the C<Inline_Stack_Push> adds a |
| 1327 | second argument. C<Inline_Stack_Void> makes sure that nothing is |
| 1328 | returned from the function. |
| 1329 | |
| 1330 | =item See Also |
| 1331 | |
| 1332 | See L<Inline::C> for more information about Stack macros. |
| 1333 | |
| 1334 | See L<perlapi> for more information about the Perl5 internal API. |
| 1335 | |
| 1336 | =item Credits |
| 1337 | |
| 1338 | =back |
| 1339 | |
| 1340 | =cut -------------------------------------------------------------------------- |
| 1341 | |
| 1342 | =head2 Evaling C |
| 1343 | |
| 1344 | =over 4 |
| 1345 | |
| 1346 | =item Problem |
| 1347 | |
| 1348 | I've totally lost my marbles and I want to generate C code at run time, |
| 1349 | and C<eval> it into Perl. How do I do this? |
| 1350 | |
| 1351 | =item Solution |
| 1352 | |
| 1353 | use Inline; |
| 1354 | use Code::Generator; |
| 1355 | |
| 1356 | my $c_code = generate('foo_function'); |
| 1357 | |
| 1358 | Inline->bind(C => $c_code); |
| 1359 | |
| 1360 | foo_function(1, 2, 3); |
| 1361 | |
| 1362 | =item Discussion |
| 1363 | |
| 1364 | I can't think of a real life application where you would want to |
| 1365 | generate C code on the fly, but at least I know know how I would do it. |
| 1366 | :) |
| 1367 | |
| 1368 | The C<bind()> function of Inline let's you bind (compile/load/execute) C |
| 1369 | functions at run time. It takes all of the same arguments as 'use Inline |
| 1370 | C => ...'. |
| 1371 | |
| 1372 | The nice thing is that once a particular snippet is compiled, it remains |
| 1373 | cached so that it doesn't need to be compiled again. I can imagine that |
| 1374 | someday a mad scientist will dream up a self generating modeling system |
| 1375 | that would run faster and faster over time. |
| 1376 | |
| 1377 | If you know such a person, have them drop me a line. |
| 1378 | |
| 1379 | =item See Also |
| 1380 | |
| 1381 | =item Credits |
| 1382 | |
| 1383 | =back |
| 1384 | |
| 1385 | =cut -------------------------------------------------------------------------- |
| 1386 | # |
| 1387 | #=head2 xxxxxxxxxxxxxxxxxxxxxxxx |
| 1388 | # |
| 1389 | #=over 4 |
| 1390 | # |
| 1391 | #=item Problem |
| 1392 | # |
| 1393 | #=item Solution |
| 1394 | # |
| 1395 | #=item Discussion |
| 1396 | # |
| 1397 | #=item See Also |
| 1398 | # |
| 1399 | #=item Credits |
| 1400 | # |
| 1401 | #=back |
| 1402 | # |
| 1403 | =cut -------------------------------------------------------------------------- |
| 1404 | |
| 1405 | =head1 SEE ALSO |
| 1406 | |
| 1407 | For generic information about Inline, see L<Inline>. |
| 1408 | |
| 1409 | For information about using Inline with C see L<Inline::C>. |
| 1410 | |
| 1411 | For information on supported languages and platforms see |
| 1412 | L<Inline-Support>. |
| 1413 | |
| 1414 | For information on writing your own Inline language support module, see |
| 1415 | L<Inline-API>. |
| 1416 | |
| 1417 | Inline's mailing list is inline@perl.org |
| 1418 | |
| 1419 | To subscribe, send email to inline-subscribe@perl.org |
| 1420 | |
| 1421 | =head1 AUTHOR |
| 1422 | |
| 1423 | Brian Ingerson <INGY@cpan.org> |
| 1424 | |
| 1425 | =head1 COPYRIGHT |
| 1426 | |
| 1427 | Copyright (c) 2001, 2002, Brian Ingerson. |
| 1428 | |
| 1429 | All Rights Reserved. This module is free software. It may be |
| 1430 | used, redistributed and/or modified under the terms of the Perl |
| 1431 | Artistic License. |
| 1432 | |
| 1433 | See http://www.perl.com/perl/misc/Artistic.html |
| 1434 | |
| 1435 | =cut |