summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--AUTHORS1
-rw-r--r--pod/perlembed.pod233
2 files changed, 124 insertions, 110 deletions
diff --git a/AUTHORS b/AUTHORS
index 081d2901db..6a3d814bd3 100644
--- a/AUTHORS
+++ b/AUTHORS
@@ -410,6 +410,7 @@ Gerard Goossen <gerard@ggoossen.net>
Gerben Wierda <G.C.Th.Wierda@AWT.nl>
Gerd Knops <gerti@BITart.com>
Gerrit P. Haase <gp@familiehaase.de>
+Gideon Israel Dsouza <gidisrael@gmail.com>
Giles Lean <giles@nemeton.com.au>
Gisle Aas <gisle@aas.no>
Glenn Linderman <perl@nevcal.com>
diff --git a/pod/perlembed.pod b/pod/perlembed.pod
index 979c944670..4560ecc786 100644
--- a/pod/perlembed.pod
+++ b/pod/perlembed.pod
@@ -20,7 +20,7 @@ Read about back-quotes and about C<system> and C<exec> in L<perlfunc>.
=item B<Use Perl from Perl?>
-Read about L<perlfunc/do> and L<perlfunc/eval> and L<perlfunc/require>
+Read about L<perlfunc/do> and L<perlfunc/eval> and L<perlfunc/require>
and L<perlfunc/use>.
=item B<Use C from C?>
@@ -77,7 +77,7 @@ Using Perl modules, which themselves use C libraries, from your C program
Embedding Perl under Win32
-=back
+=back
=head2 Compiling your C program
@@ -125,7 +125,7 @@ L<Adding a Perl interpreter to your C program>, on my Linux box:
-L/usr/local/lib/perl5/i586-linux/5.003/CORE
-o interp interp.c -lperl -lm
-(That's all one line.) On my DEC Alpha running old 5.003_05, the
+(That's all one line.) On my DEC Alpha running old 5.003_05, the
incantation is a bit different:
% cc -O2 -Olimit 2900 -DSTANDARD_C -I/usr/local/include
@@ -176,13 +176,13 @@ In a sense, perl (the C program) is a good example of embedding Perl
included in the source distribution. Here's a bastardized, non-portable
version of I<miniperlmain.c> containing the essentials of embedding:
- #include <EXTERN.h> /* from the Perl distribution */
- #include <perl.h> /* from the Perl distribution */
+ #include <EXTERN.h> /* from the Perl distribution */
+ #include <perl.h> /* from the Perl distribution */
- static PerlInterpreter *my_perl; /*** The Perl interpreter ***/
+ static PerlInterpreter *my_perl; /*** The Perl interpreter ***/
- int main(int argc, char **argv, char **env)
- {
+ int main(int argc, char **argv, char **env)
+ {
PERL_SYS_INIT3(&argc,&argv,&env);
my_perl = perl_alloc();
perl_construct(my_perl);
@@ -192,7 +192,7 @@ version of I<miniperlmain.c> containing the essentials of embedding:
perl_destruct(my_perl);
perl_free(my_perl);
PERL_SYS_TERM();
- }
+ }
Notice that we don't use the C<env> pointer. Normally handed to
C<perl_parse> as its final argument, C<env> here is replaced by
@@ -272,24 +272,24 @@ I<G_DISCARD>). Those flags, and others, are discussed in L<perlcall>.
I'll define the I<showtime> subroutine in a file called I<showtime.pl>:
- print "I shan't be printed.";
+ print "I shan't be printed.";
- sub showtime {
- print time;
- }
-
-Simple enough. Now compile and run:
+ sub showtime {
+ print time;
+ }
- % cc -o showtime showtime.c `perl -MExtUtils::Embed -e ccopts -e ldopts`
+Simple enough. Now compile and run:
- % showtime showtime.pl
- 818284590
+ % cc -o showtime showtime.c \
+ `perl -MExtUtils::Embed -e ccopts -e ldopts`
+ % showtime showtime.pl
+ 818284590
yielding the number of seconds that elapsed between January 1, 1970
(the beginning of the Unix epoch), and the moment I began writing this
sentence.
-In this particular case we don't have to call I<perl_run>, as we set
+In this particular case we don't have to call I<perl_run>, as we set
the PL_exit_flag PERL_EXIT_DESTRUCT_END which executes END blocks in
perl_destruct.
@@ -315,41 +315,43 @@ extract variables for coercion into C types. The following program,
I<string.c>, executes three Perl strings, extracting an C<int> from
the first, a C<float> from the second, and a C<char *> from the third.
- #include <EXTERN.h>
- #include <perl.h>
+ #include <EXTERN.h>
+ #include <perl.h>
- static PerlInterpreter *my_perl;
+ static PerlInterpreter *my_perl;
- main (int argc, char **argv, char **env)
- {
- char *embedding[] = { "", "-e", "0" };
+ main (int argc, char **argv, char **env)
+ {
+ char *embedding[] = { "", "-e", "0" };
- PERL_SYS_INIT3(&argc,&argv,&env);
- my_perl = perl_alloc();
- perl_construct( my_perl );
+ PERL_SYS_INIT3(&argc,&argv,&env);
+ my_perl = perl_alloc();
+ perl_construct( my_perl );
- perl_parse(my_perl, NULL, 3, embedding, NULL);
- PL_exit_flags |= PERL_EXIT_DESTRUCT_END;
- perl_run(my_perl);
+ perl_parse(my_perl, NULL, 3, embedding, NULL);
+ PL_exit_flags |= PERL_EXIT_DESTRUCT_END;
+ perl_run(my_perl);
- /** Treat $a as an integer **/
- eval_pv("$a = 3; $a **= 2", TRUE);
- printf("a = %d\n", SvIV(get_sv("a", 0)));
+ /** Treat $a as an integer **/
+ eval_pv("$a = 3; $a **= 2", TRUE);
+ printf("a = %d\n", SvIV(get_sv("a", 0)));
- /** Treat $a as a float **/
- eval_pv("$a = 3.14; $a **= 2", TRUE);
- printf("a = %f\n", SvNV(get_sv("a", 0)));
+ /** Treat $a as a float **/
+ eval_pv("$a = 3.14; $a **= 2", TRUE);
+ printf("a = %f\n", SvNV(get_sv("a", 0)));
- /** Treat $a as a string **/
- eval_pv("$a = 'rekcaH lreP rehtonA tsuJ'; $a = reverse($a);", TRUE);
- printf("a = %s\n", SvPV_nolen(get_sv("a", 0)));
+ /** Treat $a as a string **/
+ eval_pv(
+ "$a = 'rekcaH lreP rehtonA tsuJ'; $a = reverse($a);", TRUE);
+ printf("a = %s\n", SvPV_nolen(get_sv("a", 0)));
- perl_destruct(my_perl);
- perl_free(my_perl);
- PERL_SYS_TERM();
- }
+ perl_destruct(my_perl);
+ perl_free(my_perl);
+ PERL_SYS_TERM();
+ }
-All of those strange functions with I<sv> in their names help convert Perl scalars to C types. They're described in L<perlguts> and L<perlapi>.
+All of those strange functions with I<sv> in their names help convert Perl
+scalars to C types. They're described in L<perlguts> and L<perlapi>.
If you compile and run I<string.c>, you'll see the results of using
I<SvIV()> to create an C<int>, I<SvNV()> to create a C<float>, and
@@ -388,14 +390,15 @@ returns 1 if the string matches the pattern and 0 otherwise.
Given a pointer to an C<SV> and an C<=~> operation (e.g.,
C<s/bob/robert/g> or C<tr[A-Z][a-z]>), substitute() modifies the string
-within the C<SV> as according to the operation, returning the number of substitutions
-made.
+within the C<SV> as according to the operation, returning the number of
+substitutions made.
SSize_t matches(SV *string, char *pattern, AV **matches);
Given an C<SV>, a pattern, and a pointer to an empty C<AV>,
matches() evaluates C<$string =~ $pattern> in a list context, and
-fills in I<matches> with the array elements, returning the number of matches found.
+fills in I<matches> with the array elements, returning the number of matches
+found.
Here's a sample program, I<match.c>, that uses all three (long lines have
been wrapped here):
@@ -406,8 +409,8 @@ been wrapped here):
static PerlInterpreter *my_perl;
/** my_eval_sv(code, error_check)
- ** kinda like eval_sv(),
- ** but we pop the return value off the stack
+ ** kinda like eval_sv(),
+ ** but we pop the return value off the stack
**/
SV* my_eval_sv(SV *sv, I32 croak_on_error)
{
@@ -450,7 +453,8 @@ been wrapped here):
/** substitute(string, pattern)
**
- ** Used for =~ operations that modify their left-hand side (s/// and tr///)
+ ** Used for =~ operations that
+ ** modify their left-hand side (s/// and tr///)
**
** Returns the number of successful matches, and
** modifies the input string if there were any.
@@ -535,7 +539,8 @@ been wrapped here):
printf("matches: m/(wi..)/g found %d matches...\n", num_matches);
for (i = 0; i < num_matches; i++)
- printf("match: %s\n", SvPV_nolen(*av_fetch(match_list, i, FALSE)));
+ printf("match: %s\n",
+ SvPV_nolen(*av_fetch(match_list, i, FALSE)));
printf("\n");
/** Remove all vowels from text **/
@@ -560,22 +565,23 @@ been wrapped here):
which produces the output (again, long lines have been wrapped here)
- match: Text contains the word 'quarter'.
+ match: Text contains the word 'quarter'.
- match: Text doesn't contain the word 'eighth'.
+ match: Text doesn't contain the word 'eighth'.
- matches: m/(wi..)/g found 2 matches...
- match: will
- match: with
+ matches: m/(wi..)/g found 2 matches...
+ match: will
+ match: with
- substitute: s/[aeiou]//gi...139 substitutions made.
- 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
+ substitute: s/[aeiou]//gi...139 substitutions made.
+ 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
- substitute: s/Perl/C...No substitution made.
+ substitute: s/Perl/C...No substitution made.
=head2 Fiddling with the Perl stack from your C program
@@ -610,48 +616,48 @@ 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 <EXTERN.h>
- #include <perl.h>
+ #include <EXTERN.h>
+ #include <perl.h>
- static PerlInterpreter *my_perl;
+ 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 */
- 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.*/
- }
+ 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 */
+ 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[] = { "", "power.pl" };
+ int main (int argc, char **argv, char **env)
+ {
+ char *my_argv[] = { "", "power.pl" };
- PERL_SYS_INIT3(&argc,&argv,&env);
- my_perl = perl_alloc();
- perl_construct( my_perl );
+ PERL_SYS_INIT3(&argc,&argv,&env);
+ my_perl = perl_alloc();
+ perl_construct( my_perl );
- perl_parse(my_perl, NULL, 2, my_argv, (char **)NULL);
- PL_exit_flags |= PERL_EXIT_DESTRUCT_END;
- perl_run(my_perl);
+ perl_parse(my_perl, NULL, 2, my_argv, (char **)NULL);
+ PL_exit_flags |= PERL_EXIT_DESTRUCT_END;
+ perl_run(my_perl);
- PerlPower(3, 4); /*** Compute 3 ** 4 ***/
+ PerlPower(3, 4); /*** Compute 3 ** 4 ***/
- perl_destruct(my_perl);
- perl_free(my_perl);
- PERL_SYS_TERM();
- }
+ perl_destruct(my_perl);
+ perl_free(my_perl);
+ PERL_SYS_TERM();
+ }
@@ -771,7 +777,9 @@ with L<perlfunc/my> whenever possible.
#include <EXTERN.h>
#include <perl.h>
- /* 1 = clean out filename's symbol table after each request, 0 = don't */
+ /* 1 = clean out filename's symbol table after each request,
+ 0 = don't
+ */
#ifndef DO_CLEAN
#define DO_CLEAN 0
#endif
@@ -795,7 +803,8 @@ with L<perlfunc/my> whenever possible.
}
perl_construct(my_perl);
- PL_origalen = 1; /* don't let $0 assignment update the proctitle or embedding[0] */
+ PL_origalen = 1; /* don't let $0 assignment update the
+ proctitle or embedding[0] */
exitstatus = perl_parse(my_perl, NULL, 2, embedding, NULL);
PL_exit_flags |= PERL_EXIT_DESTRUCT_END;
if(!exitstatus) {
@@ -805,7 +814,8 @@ with L<perlfunc/my> whenever possible.
fgets(filename, BUFFER_SIZE, stdin)) {
filename[strlen(filename)-1] = '\0'; /* strip \n */
- /* call the subroutine, passing it the filename as an argument */
+ /* call the subroutine,
+ passing it the filename as an argument */
args[0] = filename;
call_argv("Embed::Persistent::eval_file",
G_DISCARD | G_EVAL, args);
@@ -825,7 +835,8 @@ with L<perlfunc/my> whenever possible.
Now compile:
- % cc -o persistent persistent.c `perl -MExtUtils::Embed -e ccopts -e ldopts`
+ % cc -o persistent persistent.c \
+ `perl -MExtUtils::Embed -e ccopts -e ldopts`
Here's an example script file:
@@ -983,7 +994,8 @@ the more esoteric perl_clone()).
Compile as usual:
- % cc -o multiplicity multiplicity.c `perl -MExtUtils::Embed -e ccopts -e ldopts`
+ % cc -o multiplicity multiplicity.c \
+ `perl -MExtUtils::Embed -e ccopts -e ldopts`
Run it, Run it:
@@ -991,11 +1003,12 @@ Run it, Run it:
Hi, I'm one_perl
Hi, I'm two_perl
-=head2 Using Perl modules, which themselves use C libraries, from your C program
+=head2 Using Perl modules, which themselves use C libraries, from your C
+program
If you've played with the examples above and tried to embed a script
-that I<use()>s a Perl module (such as I<Socket>) which itself uses a C or C++ library,
-this probably happened:
+that I<use()>s a Perl module (such as I<Socket>) which itself uses a C or C++
+library, this probably happened:
Can't load module Socket, dynamic loading not available in this perl.
@@ -1011,9 +1024,9 @@ calling I<perl_parse()>, handing it NULL for the second argument:
perl_parse(my_perl, NULL, argc, my_argv, NULL);
-That's where the glue code can be inserted to create the initial contact between
-Perl and linked C/C++ routines. Let's take a look some pieces of I<perlmain.c>
-to see how Perl does this:
+That's where the glue code can be inserted to create the initial contact
+between Perl and linked C/C++ routines. Let's take a look some pieces of
+I<perlmain.c> to see how Perl does this:
static void xs_init (pTHX);