text = (char *) malloc(sizeof(char) * 486); /** A long string follows! **/
sprintf(text, "%s", "When he is at a convenience store and the bill comes to some amount like 76 cents, Maynard is aware that there is something he *should* do, something that will enable him to get back a quarter, but he has no idea *what*. He fumbles through his red squeezey changepurse and gives the boy three extra pennies with his dollar, hoping that he might luck into the correct amount. The boy gives him back two of his own pennies and then the big shiny quarter that is his prize. -RICHH");
if (perl_match(text, "m/quarter/")) /** Does text contain 'quarter'? **/
printf("perl_match: Text contains the word 'quarter'.\n\n");
else
printf("perl_match: Text doesn't contain the word 'quarter'.\n\n");
if (perl_match(text, "m/eighth/")) /** Does text contain 'eighth'? **/
printf("perl_match: Text contains the word 'eighth'.\n\n");
else
printf("perl_match: Text doesn't contain the word 'eighth'.\n\n");
Now text is: Whn h s t cnvnnc str nd th bll cms t sm mnt lk 76 cnts, Mynrd s wr tht thr s smthng h *shld* d, smthng tht wll nbl hm t gt bck qrtr, bt h hs n d *wht*. H fmbls thrgh hs rd sqzy chngprs nd gvs th by thr xtr pnns wth hs dllr, hpng tht h mght lck nt th crrct mnt. Th by gvs hm bck tw f hs wn pnns nd thn th bg shny qrtr tht s hs prz. -RCHH
perl_substitute: s/Perl/C...No substitution made.
=head2 Fiddling with the Perl stack from your C program
When trying to explain stacks, most computer science textbooks mumble
something about spring-loaded columns of cafeteria plates: the last
thing you pushed on the stack is the first thing you pop off. That'll
do for our purposes: your C program will push some arguments onto "the Perl
stack", shut its eyes while some magic happens, and then pop the
results--the return value of your Perl subroutine--off the stack.
First you'll need to know how to convert between C types and Perl
types, with newSViv() and sv_setnv() and newAV() and all their
friends. They're described in L<perlguts>.
Then you'll need to know how to manipulate the Perl stack. That's
described in L<perlcall>.
Once you've understood those, embedding Perl in C is easy.
Since C has no built-in function for integer exponentiation, let's
make Perl's ** operator available to it (this is less useful than it
sounds, since Perl implements ** with C's I<pow()> function). First
I'll create a stub exponentiation function in I<power.pl>:
sub expo {
my ($a, $b) = @_;
return $a ** $b;
}
Now I'll create a C program, I<power.c>, with a function
I<PerlPower()> that contains all the perlguts necessary to push the
two arguments into I<expo()> and to pop the return value out. Take a
deep breath...
#include <stdio.h>
#include <EXTERN.h>
#include <perl.h>
static PerlInterpreter *my_perl;
static void
PerlPower(int a, int b)
{
dSP; /* initialize stack pointer */
ENTER; /* everything created after here */
SAVETMPS; /* ...is a temporary variable. */
PUSHMARK(sp); /* remember the stack pointer */
XPUSHs(sv_2mortal(newSViv(a))); /* push the base onto the stack */
XPUSHs(sv_2mortal(newSViv(b))); /* push the exponent onto stack */
PUTBACK; /* make local stack pointer global */
perl_call_pv("expo", G_SCALAR); /* call the function */
SPAGAIN; /* refresh stack pointer */
/* pop the return value from stack */
printf ("%d to the %dth power is %d.\n", a, b, POPi);
PUTBACK;
FREETMPS; /* free that return value */
LEAVE; /* ...and the XPUSHed "mortal" args.*/
}
int main (int argc, char **argv, char **env)
{
char *my_argv[2];
my_perl = perl_alloc();
perl_construct( my_perl );
my_argv[1] = (char *) malloc(10);
sprintf(my_argv[1], "power.pl");
perl_parse(my_perl, NULL, argc, my_argv, env);
PerlPower(3, 4); /*** Compute 3 ** 4 ***/
perl_destruct(my_perl);
perl_free(my_perl);
}
Compile and run:
% cc -o power power.c -L/usr/local/lib/perl5/alpha-dec_osf/CORE