Inline::C-Cookbook man page on Peanut

Man page or keyword search:  
man Server   7435 pages
apropos Keyword Search (all sections)
Output format
Peanut logo
[printable version]

C-Cookbook(3)	      User Contributed Perl Documentation	 C-Cookbook(3)

NAME
       C Cookbook - A Cornucopia of Inline C Recipes

DESCRIPTION
       It's a lot easier for most of us to cook a meal from a recipe, rather
       than just throwing things into a pot until something edible forms. So
       it is with programming as well. "Inline.pm" makes C programming for
       Perl as easy as possible. Having a set of easy to understand samples,
       makes it simpler yet.

       This Cookbook is intended to be an evergrowing repository of small yet
       complete coding examples; each showing how to accomplish a particular
       task with Inline. Each example is followed by a short discussion,
       explaining in detail the particular features that are being
       demonstrated.

       Many of these recipes are apdapted from email discussions I have had
       with Inline users around the world. It has been my experience so far,
       that Inline provides an elegant solution to almost all problems
       involving Perl and C.

       Bon Appetit!

Appetizers
       Hello, world

       Problem
	   It seems that the first thing any programmer wants to do when he
	   learns a new programming technique is to use it to greet the Earth.
	   How can I do this using Inline?

       Solution
	       use Inline C => <<'END_C';

	       void greet() {
		   printf("Hello, world\n");
	       }
	       END_C

	       greet;

       Discussion
	   Nothing too fancy here. We define a single C function "greet()"
	   which prints a message to STDOUT. One thing to note is that since
	   the Inline code comes before the function call to "greet", we can
	   call it as a bareword (no parentheses).

       See Also
	   See Inline and Inline::C for basic info about "Inline.pm".

       Credits
	   Brian Kernigan

	   Dennis Ritchie

       One Liner

       Problem
	   A concept is valid in Perl only if it can be shown to work in one
	   line.  Can Inline reduce the complexities of Perl/C interaction to
	   a one-liner?

       Solution
	       perl -e 'use Inline C=>q{void greet(){printf("Hello, world\n");}};greet'

       Discussion
	   Try doing that in XS :-)

       See Also
	   My email signature of late is:

	       perl -le 'use Inline C=>q{SV*JAxH(char*x){return newSVpvf("Just Another %s Hacker",x);}};print JAxH+Perl'

	   A bit fancier but a few bytes too long to qualify as a true one
	   liner :-(

       Credits
	   "Eli the Bearded" <elijah@workspot.net> gave me the idea that I
	   should have an Inline one-liner as a signature.

Meat & Potatoes
       Data Types

       Problem
	   How do I pass different types of data to and from Inline C
	   functions; like strings, numbers and integers?

       Solution
	       # vowels.pl
	       use Inline C;

	       $filename = $ARGV[0];
	       die "Usage: perl vowels.pl filename\n" unless -f $filename;

	       $text = join '', <>;	      # slurp input file
	       $vp = vowel_scan($text);	      # call our function
	       $vp = sprintf("%03.1f", $vp * 100);  # format for printing
	       print "The letters in $filename are $vp% vowels.\n";

	       __END__
	       __C__

	       /* Find percentage of vowels to letters */
	       double vowel_scan(char* str) {
		   int letters = 0;
		   int vowels = 0;
		   int i = 0;
		   char c;
		   char normalize = 'a' ^ 'A';
		   /* normalize forces lower case in ASCII; upper in EBCDIC */
		   char A = normalize | 'a';
		   char E = normalize | 'e';
		   char I = normalize | 'i';
		   char O = normalize | 'o';
		   char U = normalize | 'u';
		   char Z = normalize | 'z';

		   while(c = str[i++]) {
		       c |= normalize;
		       if (c >= A && c <= Z) {
			    letters++;
			    if (c == A || c == E || c == I || c == O || c == U)
				vowels++;
		       }
		   }

		   return letters ? ((double) vowels / letters) : 0.0;
	       }

       Discussion
	   This script takes a file name from the command line and prints the
	   ratio of vowels to letters in that file. "vowels.pl" uses an Inline
	   C function called "vowel_scan", that takes a string argument, and
	   returns the percentage of vowels as a floating point number between
	   0 and 1. It handles upper and lower case letters, and works with
	   ASCII and EBCDIC.  It is also quite fast.

	   Running this script produces:

	       > perl vowels.pl /usr/dict/words
	       The letters in /usr/dict/words are 37.5% vowels.

       See Also
	   The Perl Journal vol #19 has an article about Inline which uses
	   this example.

       Credits
	   This example was reprinted by permission of The Perl Journal. It
	   was edited to work with Inline v0.30 and higher.

       Variable Argument Lists

       Problem
	   How do I pass a variable-sized list of arguments to an Inline C
	   function?

       Solution
	       greet(qw(Sarathy Jan Sparky Murray Mike));

	       use Inline C => <<'END_OF_C_CODE';

	       void greet(SV* name1, ...) {
		   Inline_Stack_Vars;
		   int i;

		   for (i = 0; i < Inline_Stack_Items; i++)
		       printf("Hello %s!\n", SvPV(Inline_Stack_Item(i), PL_na));

		   Inline_Stack_Void;
	       }

	       END_OF_C_CODE

       Discussion
	   This little program greets a group of people, such as my coworkers.
	   We use the "C" ellipsis syntax: ""..."", since the list can be of
	   any size.

	   Since there are no types or names associated with each argument, we
	   can't expect XS to handle the conversions for us. We'll need to pop
	   them off the Stack ourselves. Luckily there are two functions
	   (macros) that make this a very easy task.

	   First, we need to begin our function with a ""Inline_Stack_Vars""
	   statement. This defines a few internal variables that we need to
	   access the Stack. Now we can use ""Inline_Stack_Items"", which
	   returns an integer containing the number of arguments passed to us
	   from Perl.

	   NOTE: It is important to only use ""Inline_Stack_"" macros when
	   there is an ellipsis ("...") in the argument list, or the function
	   has a return type of void.

	   Second, we use the Inline_Stack_Item(x) function to access each
	   argument where "0 <= x < items".

	   NOTE: When using a variable length argument list, you have to
	   specify at least one argument before the ellipsis. (On my compiler,
	   anyway.) When XS does it's argument checking, it will complain if
	   you pass in less than the number of defined arguments. Therefore,
	   there is currently no way to pass an empty list when a variable
	   length list is expected.

       See Also
       Credits

       Multiple Return Values

       Problem
	   How do I return a list of values from a C function?

       Solution
	       print map {"$_\n"} get_localtime(time);

	       use Inline C => <<'END_OF_C_CODE';

	       #include <time.h>

	       void get_localtime(int utc) {
		 struct tm *ltime = localtime(&utc);
		 Inline_Stack_Vars;

		 Inline_Stack_Reset;
		 Inline_Stack_Push(sv_2mortal(newSViv(ltime->tm_year)));
		 Inline_Stack_Push(sv_2mortal(newSViv(ltime->tm_mon)));
		 Inline_Stack_Push(sv_2mortal(newSViv(ltime->tm_mday)));
		 Inline_Stack_Push(sv_2mortal(newSViv(ltime->tm_hour)));
		 Inline_Stack_Push(sv_2mortal(newSViv(ltime->tm_min)));
		 Inline_Stack_Push(sv_2mortal(newSViv(ltime->tm_sec)));
		 Inline_Stack_Push(sv_2mortal(newSViv(ltime->tm_isdst)));
		 Inline_Stack_Done;
	       }
	       END_OF_C_CODE

       Discussion
	   Perl is a language where it is common to return a list of values
	   from a subroutine call instead of just a single value. C is not
	   such a language. In order to accomplish this in C we need to
	   manipulate the Perl call stack by hand. Luckily, Inline provides
	   macros to make this easy.

	   This example calls the system "localtime", and returns each of the
	   parts of the time struct; much like the perl builtin "localtime()".
	   On each stack push, we are creating a new Perl integer (SVIV) and
	   mortalizing it. The sv_2mortal() call makes sure that the reference
	   count is set properly. Without it, the program would leak memory.

	   NOTE: The "#include" statement is not really needed, because Inline
	   automatically includes the Perl headers which include almost all
	   standard system calls.

       See Also
	   For more information on the Inline stack macros, see Inline::C.

       Credits
	   Richard Anderson <starfire@zipcon.net> contributed the original
	   idea for this snippet.

       Multiple Return Values (Another Way)

       Problem
	   How can I pass back more than one value without using the Perl
	   Stack?

       Solution
	       use Inline::Files;
	       use Inline C;

	       my ($foo, $bar);
	       change($foo, $bar);

	       print "\$foo = $foo\n";
	       print "\$bar = $bar\n";

	       __C__

	       int change(SV* var1, SV* var2) {
		   sv_setpvn(var1, "Perl Rocks!", 11);
		   sv_setpvn(var2, "Inline Rules!", 13);
		   return 1;
	       }

       Discussion
	   Most perl function interfaces return values as a list of one or
	   more scalars. Very few like "chomp", will modify an input scalar in
	   place.  On the other hand, in C you do this quite often. Values are
	   passed in by reference and modified in place by the called
	   function.

	   It turns out that we can do that with Inline as well. The secret is
	   to use a type of '"SV*"' for each argument that is to be modified.
	   This ensures passing by reference, because no typemapping is
	   needed.

	   The function can then use the Perl5 API to operate on that
	   argument.  When control returns to Perl, the argument will retain
	   the value set by the C function. In this example we passed in 2
	   empty scalars and assigned values directly to them.

       See Also
       Credits
	   Ned Konz <ned@bike-nomad.com> brought this behavior to my
	   attention. He also pointed out that he is not the world famous
	   computer cyclist Steve Roberts (http://www.microship.com), but he
	   is close (http://bike-nomad.com). Thanks Ned.

       Using Memory

       Problem
	   How should I allocate buffers in my Inline C code?

       Solution
	       print greeting('Ingy');

	       use Inline C => <<'END_OF_C_CODE';

	       SV* greeting(SV* sv_name) {
		   return (newSVpvf("Hello %s!\n", SvPV(sv_name, PL_na)));
	       }

	       END_OF_C_CODE

       Discussion
	   In this example we will return the greeting to the caller, rather
	   than printing it. This would seem mighty easy, except for the fact
	   that we need to allocate a small buffer to create the greeting.

	   I would urge you to stay away from "malloc"ing your own buffer.
	   Just use Perl's built in memory management. In other words, just
	   create a new Perl string scalar. The function "newSVpv" does just
	   that. And "newSVpvf" includes "sprintf" functionality.

	   The other problem is getting rid of this new scalar. How will the
	   ref count get decremented after we pass the scalar back? Perl also
	   provides a function called "sv_2mortal". Mortal variables die when
	   the context goes out of scope. In other words, Perl will wait until
	   the new scalar gets passed back and then decrement the ref count
	   for you, thereby making it eligible for garbage collection. See
	   "perldoc perlguts".

	   In this example the "sv_2mortal" call gets done under the hood by
	   XS, because we declared the return type to be "SV*".

	   To view the generated XS code, run the command ""perl
	   -MInline=INFO,FORCE,NOCLEAN example004.pl"". This will leave the
	   build directory intact and tell you where to find it.

       See Also
       Credits

Fast Food
       Inline CGI

       Problem
	   How do I use Inline securely in a CGI environment?

       Solution
	       #!/usr/bin/perl

	       use CGI qw(:standard);
	       use Inline (Config =>
			   DIRECTORY => '/usr/local/apache/Inline',
			  );

	       print (header,
		      start_html('Inline CGI Example'),
		      h1(JAxH('Inline')),
		      end_html
		     );

	       use Inline C => <<END;
	       SV* JAxH(char* x) {
		   return newSVpvf("Just Another %s Hacker", x);
	       }
	       END

       Discussion
	   The problem with running Inline code from a CGI script is that
	   Inline writes to a build area on your disk whenever it compiles
	   code. Most CGI scripts don't (and shouldn't) be able to create a
	   directory and write into it.

	   The solution is to explicitly tell Inline which directory to use
	   with the 'use Inline Config => DIRECTORY => ...' line. Then you
	   need to give write access to that directory from the web server
	   (CGI script).

	   If you see this as a security hole, then there is another option.
	   Give write access to yourself, but read-only access to the CGI
	   script. Then run the script once by hand (from the command line).
	   This will cause Inline to precompile the C code. That way the CGI
	   will only need read access to the build directory (to load in the
	   shared library from there).

	   Just remember that whenever you change the C code, you need to
	   precompile it again.

       See Also
	   See CGI for more information on using the "CGI.pm" module.

       Credits

       mod_perl

       Problem
	   How do I use Inline with mod_perl?

       Solution
	       package Factorial;
	       use strict;
	       use Inline Config =>
			  DIRECTORY => '/usr/local/apache/Inline',
			  ENABLE => 'UNTAINT';
	       use Inline 'C';
	       Inline->init;

	       sub handler {
		   my $r = shift;
		   $r->send_http_header('text/plain');
		   printf "%3d! = %10d\n", $_, factorial($_) for 1..100;
		   return Apache::Constants::OK;
	       }

	       1;
	       __DATA__
	       __C__
	       double factorial(double x) {
		   if (x < 2)  return 1;
		   return x * factorial(x - 1)
	       }

       Discussion
	   This is a fully functional mod_perl handler that prints out the
	   factorial values for the numbers 1 to 100. Since we are using
	   Inline under mod_perl, there are a few considerations to , um,
	   consider.

	   First, mod_perl handlers are usually run with "-T" taint detection.
	   Therefore, we need to enable the UNTAINT option. The next thing to
	   deal with is the fact that this handler will most likely be loaded
	   after Perl's compile time. Since we are using the DATA section, we
	   need to use the special "init()" call. And of course we need to
	   specify a DIRECTORY that mod_perl can compile into. See the above
	   CGI example for more info.

	   Other than that, this is a pretty straightforward mod_perl handler,
	   tuned for even more speed!

       See Also
	   See Stas Bekman's upcoming O'Reilly book on mod_perl to which this
	   example was contributed.

       Credits

       Object Oriented Inline

       Problem
	   How do I implement Object Oriented programming in Perl using C
	   objects?

       Solution
	       my $obj1 = Soldier->new('Benjamin', 'Private', 11111);
	       my $obj2 = Soldier->new('Sanders', 'Colonel', 22222);
	       my $obj3 = Soldier->new('Matt', 'Sergeant', 33333);

	       for my $obj ($obj1, $obj2, $obj3) {
		   print ($obj->get_serial, ") ",
			  $obj->get_name, " is a ",
			  $obj->get_rank, "\n");
	       }

	       #---------------------------------------------------------

	       package Soldier;

	       use Inline C => <<'END';

	       typedef struct {
		   char* name;
		   char* rank;
		   long	 serial;
	       } Soldier;

	       SV* new(char* class, char* name, char* rank, long serial) {
		   Soldier* soldier = malloc(sizeof(Soldier));
		   SV*	    obj_ref = newSViv(0);
		   SV*	    obj = newSVrv(obj_ref, class);

		   soldier->name = strdup(name);
		   soldier->rank = strdup(rank);
		   soldier->serial = serial;

		   sv_setiv(obj, (IV)soldier);
		   SvREADONLY_on(obj);
		   return obj_ref;
	       }

	       char* get_name(SV* obj) {
		   return ((Soldier*)SvIV(SvRV(obj)))->name;
	       }

	       char* get_rank(SV* obj) {
		   return ((Soldier*)SvIV(SvRV(obj)))->rank;
	       }

	       long get_serial(SV* obj) {
		   return ((Soldier*)SvIV(SvRV(obj)))->serial;
	       }

	       void DESTROY(SV* obj) {
		   Soldier* soldier = (Soldier*)SvIV(SvRV(obj));
		   free(soldier->name);
		   free(soldier->rank);
		   free(soldier);
	       }
	       END

       Discussion
	   Damian Conway has given us myriad ways of implementing OOP in Perl.
	   This is one he might not have thought of.

	   The interesting thing about this example is that it uses Perl for
	   all the OO bindings while using C for the attributes and methods.

	   If you examine the Perl code everything looks exactly like a
	   regular OO example. There is a "new" method and several accessor
	   methods. The familiar 'arrow syntax' is used to invoke them.

	   In the class definition (second part) the Perl "package" statement
	   is used to name the object class or namespace. But that's where the
	   similarities end Inline takes over.

	   The idea is that we call a C subroutine called "new()" which
	   returns a blessed scalar. The scalar contains a readonly integer
	   which is a C pointer to a Soldier struct. This is our object.

	   The "new()" function needs to malloc the memory for the struct and
	   then copy the initial values into it using "strdup()". This also
	   allocates more memory (which we have to keep track of).

	   The accessor methods are pretty straightforward. They return the
	   current value of their attribute.

	   The last method "DESTROY()" is called automatically by Perl
	   whenever an object goes out of scope. This is where we can free all
	   the memory used by the object.

	   That's it. It's a very simplistic example. It doesn't show off any
	   advanced OO features, but it is pretty cool to see how easy the
	   implementation can be. The important Perl call is "newSVrv()" which
	   creates a blessed scalar.

       See Also
	   Read "Object Oriented Perl" by Damian Conway, for more useful ways
	   of doing OOP in Perl.

	   You can learn more Perl calls in perlapi. If you don't have Perl
	   5.6.0 or higher, visit
	   http://www.perldoc.com/perl5.6/pod/perlapi.html

       Credits

The Main Course
       Exposing Shared Libraries

       Problem
	   You have this great C library and you want to be able to access
	   parts of it with Perl.

       Solution
	       print get('http://www.axkit.org');

	       use Inline C => Config =>
			  LIBS => '-lghttp';
	       use Inline C => <<'END_OF_C_CODE';

	       #include <ghttp.h>

	       char *get(SV* uri) {
		  SV* buffer;
		  ghttp_request* request;

		  buffer = NEWSV(0,0);
		  request = ghttp_request_new();
		  ghttp_set_uri(request, SvPV(uri, PL_na));

		  ghttp_set_header(request, http_hdr_Connection, "close");

		  ghttp_prepare(request);
		  ghttp_process(request);

		  sv_catpv(buffer, ghttp_get_body(request));

		  ghttp_request_destroy(request);

		  return SvPV(buffer, PL_na);
	       }

	       END_OF_C_CODE

       Discussion
	   This example fetches and prints the HTML from http://www.axkit.org
	   It requires the GNOME http libraries. http://www.gnome.org

	   One of the most common questions I get is "How can I use Inline to
	   make use of some shared library?". Although it has always been
	   possible to do so, the configuration was ugly, and there were no
	   specific examples.

	   With version 0.30 and higher, you can specify the use of shared
	   libraries easily with something like this:

	       use Inline C => Config => LIBS => '-lghttp';
	       use Inline C => "code ...";

	   or

	       use Inline C => "code ...", LIBS => '-lghttp';

	   To specify a specific library path, use:

	       use Inline C => "code ...", LIBS => '-L/your/lib/path -lyourlib';

	   To specify an include path use:

	       use Inline C => "code ...",
			  LIBS => '-lghttp',
			  INC => '-I/your/inc/path';

       See Also
	   The "LIBS" and "INC" configuration options are formatted and passed
	   into MakeMaker. For more info see ExtUtils::MakeMaker. For more
	   options see Inline::C.

       Credits
	   This code was written by Matt Sergeant <matt@sergeant.org>, author
	   of many CPAN modules. The configuration syntax has been modified
	   for use with Inline v0.30.

       Automatic Function Wrappers

       Problem
	   You have some functions in a C library that you want to access from
	   Perl exactly as you would from C.

       Solution
	   The error function "erf()" is probably defined in your standard
	   math library. Annoyingly, Perl does not let you access it. To print
	   out a small table of its values, just say:

	       perl -le 'use Inline C => q{ double erf(double); }, ENABLE => "AUTOWRAP"; print "$_ @{[erf($_)]}" for (0..10)'

	   The excellent "Term::ReadLine::Gnu" implements Term::ReadLine using
	   the GNU ReadLine library. Here is an easy way to access just
	   "readline()" from that library:

	       package MyTerm;

	       use Inline C => Config =>
			  ENABLE => AUTOWRAP =>
			  LIBS => "-lreadline -lncurses -lterminfo -ltermcap ";
	       use Inline C => q{ char * readline(char *); };

	       package main;
	       my $x = MyTerm::readline("xyz: ");

	   Note however that it fails to "free()" the memory returned by
	   readline, and that "Term::ReadLine::Gnu" offers a much richer
	   interface.

       Discussion
	   We access existing functions by merely showing Inline their
	   declarations, rather than a full definition. Of course the function
	   declared must exist, either in a library already linked to Perl or
	   in a library specified using the "LIBS" option.

	   The first example wraps a function from the standard math library,
	   so Inline requires no additional "LIBS" directive. The second uses
	   the Config option to specify the libraries that contain the actual
	   compiled C code.

	   This behavior is always disabled by default. You must enable the
	   "AUTOWRAP" option to make it work.

       See Also
	   "readline", "Term::ReadLine::Gnu"

       Credits
	   GNU ReadLine was written by Brian Fox <bfox@ai.mit.edu> and Chet
	   Ramey <chet@ins.cwru.edu>. Term::ReadLine::Gnu was written by Hiroo
	   Hayashi <hiroo.hayashi@computer.org>. Both are far richer than the
	   slim interface given here!

	   The idea of producing wrapper code given only a function
	   declaration is taken from Swig by David M. Beazley
	   <beazley@cs.uchicago.edu>.

	   Ingy's inline editorial insight:

	   This entire entry was contributed by Ariel Scolnicov
	   <ariels@compugen.co.il>. Ariel also first suggested the idea for
	   Inline to support function declaration processing.

       Complex Data

       Problem
	   How do I deal with complex data types like hashes in Inline C?

       Solution
	       use Inline C => <<'END_OF_C_CODE';

	       void dump_hash(SV* hash_ref) {
		   HV* hash;
		   HE* hash_entry;
		   int num_keys, i;
		   SV* sv_key;
		   SV* sv_val;

		   if (! SvROK(hash_ref))
		       croak("hash_ref is not a reference");

		   hash = (HV*)SvRV(hash_ref);
		   num_keys = hv_iterinit(hash);
		   for (i = 0; i < num_keys; i++) {
		       hash_entry = hv_iternext(hash);
		       sv_key = hv_iterkeysv(hash_entry);
		       sv_val = hv_iterval(hash, hash_entry);
		       printf("%s => %s\n", SvPV(sv_key, PL_na), SvPV(sv_val, PL_na));
		   }
		   return;
	       }

	       END_OF_C_CODE

	       my %hash = (
			   Author => "Brian Ingerson",
			   Nickname => "INGY",
			   Module => "Inline.pm",
			   Version => "0.30",
			   Language => "C",
			  );

	       dump_hash(\%hash);

       Discussion
	   The world is not made of scalars alone, although they are
	   definitely the easiest creatures to deal with, when doing Inline
	   stuff.  Sometimes we need to deal with arrays, hashes, and code
	   references, among other things.

	   Since Perl subroutine calls only pass scalars as arguments, we'll
	   need to use the argument type "SV*" and pass references to more
	   complex types.

	   The above program dumps the key/value pairs of a hash. To figure it
	   out, just curl up with perlapi for a couple hours. Actually, its
	   fairly straight forward once you are familiar with the calls.

	   Note the "croak" function call. This is the proper way to die from
	   your C extensions.

       See Also
	   See perlapi for information about the Perl5 internal API.

       Credits

       Hash of Lists

       Problem
	   How do I create a Hash of Lists from C?

       Solution
	       use Inline C;
	       use Data::Dumper;

	       $hash_ref = load_data("./cartoon.txt");
	       print Dumper $hash_ref;

	       __END__
	       __C__

	       static int next_word(char**, char*);

	       SV* load_data(char* file_name) {
		   char buffer[100], word[100], * pos;
		   AV* array;
		   HV* hash = newHV();
		   FILE* fh = fopen(file_name, "r");

		   while (fgets(pos = buffer, sizeof(buffer), fh)) {
		       if (next_word(&pos, word)) {
			   hv_store(hash, word, strlen(word),
				   newRV_noinc((SV*)array = newAV()), 0);
			   while (next_word(&pos, word))
			       av_push(array, newSVpvf("%s", word));
		       }
		   }
		   fclose(fh);
		   return newRV_noinc((SV*) hash);
	       }

	       static int next_word(char** text_ptr, char* word) {
		   char* text = *text_ptr;
		   while(*text != '\0' &&
			 *text <= ' ')
		       text++;
		   if (*text <= ' ')
		       return 0;
		   while(*text != '\0' &&
			 *text > ' ') {
		       *word++ = *text++;
		   }
		   *word = '\0';
		   *text_ptr = text;
		   return 1;
	       }

       Discussion
	   This is one of the larger recipes. But when you consider the number
	   of calories it has, it's not so bad. The function "load_data" takes
	   the name of a file as it's input. The file "cartoon.text" might
	   look like:

	       flintstones fred barney
	       jetsons	   george jane elroy
	       simpsons	   homer marge bart

	   The function will read the file, parsing each line into words. Then
	   it will create a new hash, whereby the first word in a line becomes
	   a hash key and the remaining words are put into an array whose
	   reference becomes the hash value. The output looks like this:

	       $VAR1 = {
			 'flintstones' => [
					    'fred',
					    'barney'
					  ],
			 'simpsons' => [
					 'homer',
					 'marge',
					 'bart'
				       ],
			 'jetsons' => [
					'george',
					'jane',
					'elroy'
				      ]
		       };

       See Also
	   See perlapi for information about the Perl5 internal API.

       Credits
	   Al Danial <alnd@pacbell.net> requested a solution to this on
	   comp.lang.perl.misc. He borrowed the idea from the "Hash of Lists"
	   example in the Camel book.

Just Desserts
       Win32

       Problem
	   How do I access Win32 DLL-s using Inline?

       Solution
	       use Inline C => DATA =>
			  LIBS => '-luser32';

	       $text = "@ARGV" || 'Inline.pm works with MSWin32. Scary...';

	       WinBox('Inline Text Box', $text);

	       __END__
	       __C__

	       #include <windows.h>

	       int WinBox(char* Caption, char* Text) {
		 return MessageBoxA(0, Text, Caption, 0);
	       }

       Discussion
	   This example runs on MS Windows. It makes a text box appear on the
	   screen which contains a message of your choice.

	   The important thing is that its proof that you can use Inline to
	   interact with Windows DLL-s. Very scary indeed. 8-o

	   To use Inline on Windows with ActivePerl (
	   http://www.ActiveState.com ) you'll need MS Visual Studio. You can
	   also use the Cygwin environment, available at http://www.cygwin.com
	   .

       See Also
	   See Inline-Support for more info on MSWin32 programming with
	   Inline.

       Credits
	   This example was adapted from some sample code written by Garrett
	   Goebel <garrett@scriptpro.com>

       Embedding Perl in C

       Problem
	   How do I use Perl from a regular C program?

       Solution
	       #!/usr/bin/cpr

	       int main(void) {

		   printf("Using Perl version %s from a C program!\n\n",
			  CPR_eval("use Config; $Config{version};"));

		   CPR_eval("use Data::Dumper;");
		   CPR_eval("print Dumper \\%INC;");

		   return 0;

	       }

       Discussion
	   By using CPR. (C Perl Run)

	   This example uses another Inline module, "Inline::CPR", available
	   separately on CPAN. When you install this module it also installs a
	   binary interpreter called "/usr/bin/cpr". (The path may be
	   different on your system)

	   When you feed a C program to the CPR interpreter, it automatically
	   compiles and runs your code using Inline. This gives you full
	   access to the Perl internals. CPR also provides a set of easy to
	   use C macros for calling Perl internals.

	   This means that you can effectively "run" C source code by putting
	   a CPR hashbang as the first line of your C program.

       See Also
	   See Inline::CPR for more information on using CPR.

	   "Inline::CPR" can be obtained from
	   http://search.cpan.org/search?dist=Inline-CPR

       Credits
	   Randal Schwartz <merlyn@stonehenge.com>, Randolph Bentson
	   <bentson@grieg.holmsjoen.com>, Richard Anderson
	   <starfire@zipcon.net>, and Tim Maher <tim@consultix-inc.com> helped
	   me figure out how to write a program that would work as a hashbang.

Entertaining Guests
       As of version 0.30, Inline has the ability to work in cooperation with
       other modules that want to expose a C API of their own. The general
       syntax for doing this is:

	   use Inline with => 'Module';
	   use Inline C => ... ;

       This tells "Module" to pass configuration options to Inline. Options
       like typemaps, include paths, and external libraries, are all resolved
       automatically so you can just concentrate on writing the functions.

       Event handling with Event.pm

       Problem
	   You need to write a C callback for the "Event.pm" module. Can this
	   be done more easily with Inline?

       Solution
	       use Inline with => 'Event';

	       Event->timer(desc     => 'Timer #1',
			    interval => 2,
			    cb	     => \&my_callback,
			   );

	       Event->timer(desc     => 'Timer #2',
			    interval => 3,
			    cb	     => \&my_callback,
			   );

	       print "Starting...\n";
	       Event::loop;

	       use Inline C => <<'END';
	       void my_callback(pe_event* event) {
		   pe_timer * watcher = event->up;

		   printf("%s\n\tEvent priority = %d\n\tWatcher priority = %d\n\n",
			  SvPVX(watcher->base.desc),
			  event->prio,
			  watcher->base.prio
			 );
	       }
	       END

       Discussion
	   The first line tells Inline to load the "Event.pm" module. Inline
	   then queries "Event" for configuration information. It gets the
	   name and location of Event's header files, typemaps and shared
	   objects. The parameters that "Event" returns look like:

	       INC => "-I $path/Event",
	       TYPEMAPS => "$path/Event/typemap",
	       MYEXTLIB => "$path/auto/Event/Event.$so",
	       AUTO_INCLUDE => '#include "EventAPI.h"',
	       BOOT => 'I_EVENT_API("Inline");',

	   Doing all of this automatically allows you, the programmer, to
	   simply write a function that receives a pointer of type
	   'pe_event*'. This gives you access to the "Event" structure that
	   was passed to you.

	   In this example, I simply print values out of the structure. The
	   Perl code defines 2 timer events which each invoke the same
	   callback. The first one, every two seconds, and the second one,
	   every three seconds.

	   As of this writing, "Event.pm" is the only CPAN module that works
	   in cooperation with Inline.

       See Also
	   Read the "Event.pm" documentation for more information. It contains
	   a tutorial showing several examples of using Inline with "Event".

       Credits
	   Jochen Stenzel <perl@jochen-stenzel.de> originally came up with the
	   idea of mixing Inline and "Event". He also authored the "Event"
	   tutorial.

	   Joshua Pritikin <joshua.pritikin@db.com> is the author of
	   "Event.pm".

Food for Thought
       Calling C from both Perl and C

       Problem
	   I'd like to be able to call the same C function from both Perl and
	   C.  Also I like to define a C function that doesn't get bound to
	   Perl.  How do I do that?

       Solution
	       print "9 + 5 = ", add(9, 5), "\n";
	       print "SQRT(9^2 + 5^2) = ", pyth(9, 5), "\n";
	       print "9 * 5 = ", mult(9, 5), "\n";

	       use Inline C => <<'END_C';
	       int add(int x, int y) {
		   return x + y;
	       }
	       static int mult(int x, int y) {
		   return x * y;
	       }
	       double pyth(int x, int y) {
		   return sqrt(add(mult(x, x), mult(y, y)));
	       }
	       END_C

       Discussion
	   The program produces:

	       9 + 5 = 14
	       SQRT(9^2 + 5^2) = 10.295630140987
	       Can't locate auto/main/mult.al in @INC ...

	   Every Inline function that is bound to Perl is also callable by C.
	   You don't have to do anything special. Inline arranges it so that
	   all the typemap code gets done by XS and is out of sight. By the
	   time the C function receives control, everything has been converted
	   from Perl to C.

	   Of course if your function manipulates the Perl Stack, you probably
	   don't want to call it from C (unless you really know what you're
	   doing).

	   If you declare a function as "static", Inline won't bind it to
	   Perl.  That's why we were able to call "mult()" from C but the call
	   failed from Perl.

       See Also
       Credits

       Calling Perl from C

       Problem
	   So now that I can call C from Perl, how do I call a Perl subroutine
	   from an Inline C function.

       Solution
	       use Inline C;

	       c_func_1('This is the first line');
	       c_func_2('This is the second line');

	       sub perl_sub_1 {
		   print map "$_\n", @_;
	       }

	       __DATA__
	       __C__

	       void c_func_1(SV* text) {
		   c_func_2(text);
	       }

	       void c_func_2(SV* text) {
		   Inline_Stack_Vars;
		   Inline_Stack_Push(newSVpvf("Plus an extra line"));
		   Inline_Stack_Done;
		   perl_call_pv("main::perl_sub_1", 0);
		   Inline_Stack_Void;
	       }

       Discussion
	   Actually, this program demonstrates calling a C function which
	   calls another C function which in turn calls a Perl subroutine.

	   The nice thing about Inline C functions is that you can call them
	   from both Perl-space and C-space. That's because Inline creates a
	   wrapper function around each C function. When you use Perl to call
	   C you're actually calling that function's wrapper. The wrapper
	   handles typemapping and Stack management, and then calls your C
	   function.

	   The first time we call "c_func_1" which calls "c_func_2". The
	   second time we call "c_func_2" directly. "c_func_2" calls the Perl
	   subroutine ("perl_sub_1") using the internal "perl_call_pv"
	   function. It has to put arguments on the stack by hand. Since there
	   is already one argument on the stack when we enter the function,
	   the "Inline_Stack_Push" adds a second argument. "Inline_Stack_Void"
	   makes sure that nothing is returned from the function.

       See Also
	   See Inline::C for more information about Stack macros.

	   See perlapi for more information about the Perl5 internal API.

       Credits

       Evaling C

       Problem
	   I've totally lost my marbles and I want to generate C code at run
	   time, and "eval" it into Perl. How do I do this?

       Solution
	       use Inline;
	       use Code::Generator;

	       my $c_code = generate('foo_function');

	       Inline->bind(C => $c_code);

	       foo_function(1, 2, 3);

       Discussion
	   I can't think of a real life application where you would want to
	   generate C code on the fly, but at least I know know how I would do
	   it.	:)

	   The "bind()" function of Inline let's you bind
	   (compile/load/execute) C functions at run time. It takes all of the
	   same arguments as 'use Inline C => ...'.

	   The nice thing is that once a particular snippet is compiled, it
	   remains cached so that it doesn't need to be compiled again. I can
	   imagine that someday a mad scientist will dream up a self
	   generating modeling system that would run faster and faster over
	   time.

	   If you know such a person, have them drop me a line.

       See Also
       Credits

SEE ALSO
       For generic information about Inline, see Inline.

       For information about using Inline with C see Inline::C.

       For information on supported languages and platforms see Inline-
       Support.

       For information on writing your own Inline language support module, see
       Inline-API.

       Inline's mailing list is inline@perl.org

       To subscribe, send email to inline-subscribe@perl.org

AUTHOR
       Brian Ingerson <INGY@cpan.org>

COPYRIGHT
       Copyright (c) 2001, 2002, Brian Ingerson.

       All Rights Reserved. This module is free software. It may be used,
       redistributed and/or modified under the terms of the Perl Artistic
       License.

       See http://www.perl.com/perl/misc/Artistic.html

POD ERRORS
       Hey! The above document had some coding errors, which are explained
       below:

       Around line 1403:
	   =cut found outside a pod block.  Skipping to next block.

perl v5.10.0			  2002-10-20			 C-Cookbook(3)
[top]

List of man pages available for Peanut

Copyright (c) for man pages and the logo by the respective OS vendor.

For those who want to learn more, the polarhome community provides shell access and support.

[legal] [privacy] [GNU] [policy] [cookies] [netiquette] [sponsors] [FAQ]
Tweet
Polarhome, production since 1999.
Member of Polarhome portal.
Based on Fawad Halim's script.
....................................................................
Vote for polarhome
Free Shell Accounts :: the biggest list on the net