If the B<ExtUtils::Embed> module isn't part of your Perl distribution,
you can retrieve it from
-http://www.perl.com/perl/CPAN/modules/by-module/ExtUtils/. (If
-this documentation came from your Perl distribution, then you're
+http://www.perl.com/perl/CPAN/modules/by-module/ExtUtils/
+(If this documentation came from your Perl distribution, then you're
running 5.004 or better and you already have it.)
The B<ExtUtils::Embed> kit on CPAN also contains all source code for
int main(int argc, char **argv, char **env)
{
+ PERL_SYS_INIT3(&argc,&argv,&env);
my_perl = perl_alloc();
perl_construct(my_perl);
PL_exit_flags |= PERL_EXIT_DESTRUCT_END;
perl_run(my_perl);
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
-C<NULL>, which means that the current environment will be used.
+C<NULL>, which means that the current environment will be used. The macros
+PERL_SYS_INIT3() and PERL_SYS_TERM() provide system-specific tune up
+of the C runtime environment necessary to run Perl interpreters; since
+PERL_SYS_INIT3() may change C<env>, it may be more appropriate to provide
+C<env> as an argument to perl_parse().
Now compile this program (I'll call it I<interp.c>) into an executable:
int main(int argc, char **argv, char **env)
{
char *args[] = { NULL };
+ PERL_SYS_INIT3(&argc,&argv,&env);
my_perl = perl_alloc();
perl_construct(my_perl);
perl_destruct(my_perl);
perl_free(my_perl);
+ PERL_SYS_TERM();
}
where I<showtime> is a Perl subroutine that takes no arguments (that's the
STRLEN n_a;
char *embedding[] = { "", "-e", "0" };
+ PERL_SYS_INIT3(&argc,&argv,&env);
my_perl = perl_alloc();
perl_construct( my_perl );
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>.
#include <EXTERN.h>
#include <perl.h>
+ static PerlInterpreter *my_perl;
+
/** my_eval_sv(code, error_check)
** kinda like eval_sv(),
** but we pop the return value off the stack
main (int argc, char **argv, char **env)
{
- PerlInterpreter *my_perl = perl_alloc();
char *embedding[] = { "", "-e", "0" };
AV *match_list;
I32 num_matches, i;
- SV *text = NEWSV(1099,0);
+ SV *text;
STRLEN n_a;
+ 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;
+ text = NEWSV(1099,0);
sv_setpv(text, "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 (match(text, "m/quarter/")) /** Does text contain 'quarter'? **/
PL_perl_destruct_level = 1;
perl_destruct(my_perl);
perl_free(my_perl);
+ PERL_SYS_TERM();
}
which produces the output (again, long lines have been wrapped here)
{
char *my_argv[] = { "", "power.pl" };
+ PERL_SYS_INIT3(&argc,&argv,&env);
my_perl = perl_alloc();
perl_construct( my_perl );
perl_destruct(my_perl);
perl_free(my_perl);
+ PERL_SYS_TERM();
}
#define DO_CLEAN 0
#endif
- static PerlInterpreter *perl = NULL;
+ #define BUFFER_SIZE 1024
+
+ static PerlInterpreter *my_perl = NULL;
int
main(int argc, char **argv, char **env)
{
char *embedding[] = { "", "persistent.pl" };
char *args[] = { "", DO_CLEAN, NULL };
- char filename [1024];
+ char filename[BUFFER_SIZE];
int exitstatus = 0;
STRLEN n_a;
- if((perl = perl_alloc()) == NULL) {
+ PERL_SYS_INIT3(&argc,&argv,&env);
+ if((my_perl = perl_alloc()) == NULL) {
fprintf(stderr, "no memory!");
exit(1);
}
- perl_construct(perl);
+ perl_construct(my_perl);
- exitstatus = perl_parse(perl, NULL, 2, embedding, NULL);
+ exitstatus = perl_parse(my_perl, NULL, 2, embedding, NULL);
PL_exit_flags |= PERL_EXIT_DESTRUCT_END;
if(!exitstatus) {
- exitstatus = perl_run(perl);
+ exitstatus = perl_run(my_perl);
- while(printf("Enter file name: ") && gets(filename)) {
+ while(printf("Enter file name: ") &&
+ fgets(filename, BUFFER_SIZE, stdin)) {
+ filename[strlen(filename)-1] = '\0'; /* strip \n */
/* call the subroutine, passing it the filename as an argument */
args[0] = filename;
call_argv("Embed::Persistent::eval_file",
}
PL_perl_destruct_level = 0;
- perl_destruct(perl);
- perl_free(perl);
+ perl_destruct(my_perl);
+ perl_free(my_perl);
+ PERL_SYS_TERM();
exit(exitstatus);
}
int main(int argc, char **argv, char **env)
{
- PerlInterpreter
- *one_perl = perl_alloc(),
- *two_perl = perl_alloc();
+ PerlInterpreter *one_perl, *two_perl;
char *one_args[] = { "one_perl", SAY_HELLO };
char *two_args[] = { "two_perl", SAY_HELLO };
+ PERL_SYS_INIT3(&argc,&argv,&env);
+ one_perl = perl_alloc();
+ two_perl = perl_alloc();
+
PERL_SET_CONTEXT(one_perl);
perl_construct(one_perl);
PERL_SET_CONTEXT(two_perl);
perl_free(one_perl);
PERL_SET_CONTEXT(two_perl);
perl_free(two_perl);
+ PERL_SYS_TERM();
}
Note the calls to PERL_SET_CONTEXT(). These are necessary to initialize
This path can be added via the Tools -> Options -> Directories menu.
Finally, select Build -> Build interp.exe and you're ready to go.
+=head1 Hiding Perl_
+
+If you completely hide the short forms forms of the Perl public API,
+add -DPERL_NO_SHORT_NAMES to the compilation flags. This means that
+for example instead of writing
+
+ warn("%d bottles of beer on the wall", bottlecount);
+
+you will have to write the explicit full form
+
+ Perl_warn(aTHX_ "%d bottles of beer on the wall", bottlecount);
+
+(See L<perlguts/Background and PERL_IMPLICIT_CONTEXT for the explanation
+of the C<aTHX_>.> ) Hiding the short forms is very useful for avoiding
+all sorts of nasty (C preprocessor or otherwise) conflicts with other
+software packages (Perl defines about 2400 APIs with these short names,
+take or leave few hundred, so there certainly is room for conflict.)
+
=head1 MORAL
You can sometimes I<write faster code> in C, but
=head1 AUTHOR
-Jon Orwant <F<orwant@tpj.com>> and Doug MacEachern
-<F<dougm@osf.org>>, with small contributions from Tim Bunce, Tom
+Jon Orwant <F<orwant@media.mit.edu>> and Doug MacEachern
+<F<dougm@covalent.net>>, with small contributions from Tim Bunce, Tom
Christiansen, Guy Decoux, Hallvard Furuseth, Dov Grobgeld, and Ilya
Zakharevich.
Doug MacEachern has an article on embedding in Volume 1, Issue 4 of
-The Perl Journal (http://tpj.com). Doug is also the developer of the
+The Perl Journal ( http://www.tpj.com/ ). Doug is also the developer of the
most widely-used Perl embedding: the mod_perl system
(perl.apache.org), which embeds Perl in the Apache web server.
Oracle, Binary Evolution, ActiveState, and Ben Sugars's nsapi_perl