X-Git-Url: https://perl5.git.perl.org/perl5.git/blobdiff_plain/a2722ac963c473daf784eb7bed19dab587ac5fe6..3f76ddeebb0763514a58845b2645ed8edced9d12:/pod/perlembed.pod diff --git a/pod/perlembed.pod b/pod/perlembed.pod index 0bd569f..1144e43 100644 --- a/pod/perlembed.pod +++ b/pod/perlembed.pod @@ -173,7 +173,7 @@ information you may find useful. In a sense, perl (the C program) is a good example of embedding Perl (the language), so I'll demonstrate embedding with I, -included in the source distribution. Here's a bastardized, nonportable +included in the source distribution. Here's a bastardized, non-portable version of I containing the essentials of embedding: #include /* from the Perl distribution */ @@ -196,11 +196,20 @@ version of I containing the essentials of embedding: Notice that we don't use the C pointer. Normally handed to C as its final argument, C here is replaced by -C, 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, it may be more appropriate to provide -C as an argument to perl_parse(). +C, 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; +they should only be called once regardless of how many interpreters you +create or destroy. Call PERL_SYS_INIT3() before you create your first +interpreter, and PERL_SYS_TERM() after you free your last interpreter. + +Since PERL_SYS_INIT3() may change C, it may be more appropriate to +provide C as an argument to perl_parse(). + +Also notice that no matter what arguments you pass to perl_parse(), +PERL_SYS_INIT3() must be invoked on the C main() argc, argv and env and +only once. Now compile this program (I'll call it I) into an executable: @@ -313,7 +322,6 @@ the first, a C from the second, and a C from the third. main (int argc, char **argv, char **env) { - STRLEN n_a; char *embedding[] = { "", "-e", "0" }; PERL_SYS_INIT3(&argc,&argv,&env); @@ -326,15 +334,15 @@ the first, a C from the second, and a C from the third. /** Treat $a as an integer **/ eval_pv("$a = 3; $a **= 2", TRUE); - printf("a = %d\n", SvIV(get_sv("a", FALSE))); + 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", FALSE))); + 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(get_sv("a", FALSE), n_a)); + printf("a = %s\n", SvPV_nolen(get_sv("a", 0))); perl_destruct(my_perl); perl_free(my_perl); @@ -352,14 +360,13 @@ I to create a string: a = Just Another Perl Hacker In the example above, we've created a global variable to temporarily -store the computed value of our eval'd expression. It is also +store the computed value of our eval'ed expression. It is also possible and in most cases a better strategy to fetch the return value from I instead. Example: ... - STRLEN n_a; SV *val = eval_pv("reverse 'rekcaH lreP rehtonA tsuJ'", TRUE); - printf("%s\n", SvPV(val,n_a)); + printf("%s\n", SvPV_nolen(val)); ... This way, we avoid namespace pollution by not creating global @@ -406,7 +413,7 @@ been wrapped here): { dSP; SV* retval; - STRLEN n_a; + PUSHMARK(SP); eval_sv(sv, G_SCALAR); @@ -416,7 +423,7 @@ been wrapped here): PUTBACK; if (croak_on_error && SvTRUE(ERRSV)) - croak(SvPVx(ERRSV, n_a)); + croak(SvPVx_nolen(ERRSV)); return retval; } @@ -430,11 +437,10 @@ been wrapped here): I32 match(SV *string, char *pattern) { - SV *command = NEWSV(1099, 0), *retval; - STRLEN n_a; + SV *command = newSV(0), *retval; sv_setpvf(command, "my $string = '%s'; $string =~ %s", - SvPV(string,n_a), pattern); + SvPV_nolen(string), pattern); retval = my_eval_sv(command, TRUE); SvREFCNT_dec(command); @@ -452,16 +458,15 @@ been wrapped here): I32 substitute(SV **string, char *pattern) { - SV *command = NEWSV(1099, 0), *retval; - STRLEN n_a; + SV *command = newSV(0), *retval; sv_setpvf(command, "$string = '%s'; ($string =~ %s)", - SvPV(*string,n_a), pattern); + SvPV_nolen(*string), pattern); retval = my_eval_sv(command, TRUE); SvREFCNT_dec(command); - *string = get_sv("string", FALSE); + *string = get_sv("string", 0); return SvIV(retval); } @@ -475,18 +480,17 @@ been wrapped here): I32 matches(SV *string, char *pattern, AV **match_list) { - SV *command = NEWSV(1099, 0); + SV *command = newSV(0); I32 num_matches; - STRLEN n_a; sv_setpvf(command, "my $string = '%s'; @array = ($string =~ %s)", - SvPV(string,n_a), pattern); + SvPV_nolen(string), pattern); my_eval_sv(command, TRUE); SvREFCNT_dec(command); - *match_list = get_av("array", FALSE); - num_matches = av_len(*match_list) + 1; /** assume $[ is 0 **/ + *match_list = get_av("array", 0); + num_matches = av_len(*match_list) + 1; return num_matches; } @@ -497,7 +501,6 @@ been wrapped here): AV *match_list; I32 num_matches, i; SV *text; - STRLEN n_a; PERL_SYS_INIT3(&argc,&argv,&env); my_perl = perl_alloc(); @@ -505,7 +508,7 @@ been wrapped here): perl_parse(my_perl, NULL, 3, embedding, NULL); PL_exit_flags |= PERL_EXIT_DESTRUCT_END; - text = NEWSV(1099,0); + text = newSV(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 " @@ -532,7 +535,7 @@ 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(*av_fetch(match_list, i, FALSE),n_a)); + printf("match: %s\n", SvPV_nolen(*av_fetch(match_list, i, FALSE))); printf("\n"); /** Remove all vowels from text **/ @@ -540,7 +543,7 @@ been wrapped here): if (num_matches) { printf("substitute: s/[aeiou]//gi...%d substitutions made.\n", num_matches); - printf("Now text is: %s\n\n", SvPV(text,n_a)); + printf("Now text is: %s\n\n", SvPV_nolen(text)); } /** Attempt a substitution **/ @@ -784,7 +787,6 @@ with L whenever possible. char *args[] = { "", DO_CLEAN, NULL }; char filename[BUFFER_SIZE]; int exitstatus = 0; - STRLEN n_a; PERL_SYS_INIT3(&argc,&argv,&env); if((my_perl = perl_alloc()) == NULL) { @@ -810,7 +812,7 @@ with L whenever possible. /* check $@ */ if(SvTRUE(ERRSV)) - fprintf(stderr, "eval error: %s\n", SvPV(ERRSV,n_a)); + fprintf(stderr, "eval error: %s\n", SvPV_nolen(ERRSV)); } } @@ -915,6 +917,8 @@ C<-Dusemultiplicity> option otherwise some interpreter variables may not be initialized correctly between consecutive runs and your application may crash. +See also L. + Using C<-Dusethreads -Duseithreads> rather than C<-Dusemultiplicity> is more appropriate if you intend to run multiple interpreters concurrently in different threads, because it enables support for @@ -927,7 +931,6 @@ Let's give it a try: #include /* we're going to embed two interpreters */ - /* we're going to embed two interpreters */ #define SAY_HELLO "-e", "print qq(Hi, I'm $^X\n)" @@ -1096,7 +1099,7 @@ 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, +If you completely hide the short forms of the Perl public API, add -DPERL_NO_SHORT_NAMES to the compilation flags. This means that for example instead of writing