Anonymous Monk has asked for the wisdom of the Perl Monks concerning the following question:

Hi Monks,

Today I've started to study perlembed, Here is the first code example in Perlembed:

#include <EXTERN.h> /* from the Perl distribution */ #include <perl.h> /* from the Perl distribution * +/ static PerlInterpreter *my_perl; /*** The Perl interpreter *** +/ 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_parse(my_perl, NULL, argc, argv, (char **)NULL); perl_run(my_perl); perl_destruct(my_perl); perl_free(my_perl); PERL_SYS_TERM(); exit(EXIT_SUCCESS); }
Ican build it successfully, and it works as expected.(windows 10, strawberry perl 5.32) But if I change interpreter variable name to his_perl, it doesn't work!
#include <EXTERN.h> #include <perl.h> static PerlInterpreter *his_perl ; /*** The Perl interpreter * +**/ int main(int argc, char **argv, char **env) { PERL_SYS_INIT3(&argc,&argv,&env); PERL_SYS_TERM(); his_perl = perl_alloc(); perl_construct(his_perl); PL_exit_flags |= PERL_EXIT_DESTRUCT_END; perl_parse(his_perl, NULL, argc, argv, (char **)NULL); perl_run(his_perl); perl_destruct(his_perl); perl_free(his_perl); exit(EXIT_SUCCESS); }
It can't be build, and complains identifier "my_perl" is undefined. I notice in perl.h aTHX hard code define to my_perl, I guess that is the reason why his_perl version can't be built. But why is this name(my_perl) so important, that it should write it into perl.h? Please enlighten me.

Replies are listed 'Best First'.
Re: perl interpreter must be named my_perl?
by Corion (Patriarch) on Nov 30, 2023 at 08:03 UTC

    Yes, from looking at perl.h, the aTHX macro (and many other macros) hardcode my_perl as the variable name of the Perl interpreter. I think this is mostly so you don't have to pass that variable as a parameter everywhere.

    Looking at perlembed, I don't find this requirement mentioned, so a bug report to document that seems plausible.

    Allowing to change the name of that variable would increase the complexity of the macros and the usage I think, so this would be a lot of work for little gain. But the documentation should be explicit about this.

      Allowing to change the name of that variable would increase the complexity of the macros and the usage I think, so this would be a lot of work for little gain. But the documentation should be explicit about this.

      But on the section of "Maintaining multiple interpreter instances", Below code (different name) could be built and runs well.( the author cleverly avoid all macros which include my_perl)
      #include <EXTERN.h> #include <perl.h> /* we're going to embed two interpreters */ #define SAY_HELLO "-e", "print qq(Hi, I'm $^X\n)" int main(int argc, char **argv, char **env) { PerlInterpreter *one_perl, *two_perl; char *one_args[] = { "one_perl", SAY_HELLO, NULL }; char *two_args[] = { "two_perl", SAY_HELLO, NULL }; 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_construct(two_perl); PERL_SET_CONTEXT(one_perl); perl_parse(one_perl, NULL, 3, one_args, (char **)NULL); PERL_SET_CONTEXT(two_perl); perl_parse(two_perl, NULL, 3, two_args, (char **)NULL); PERL_SET_CONTEXT(one_perl); perl_run(one_perl); PERL_SET_CONTEXT(two_perl); perl_run(two_perl); PERL_SET_CONTEXT(one_perl); perl_destruct(one_perl); PERL_SET_CONTEXT(two_perl); perl_destruct(two_perl); PERL_SET_CONTEXT(one_perl); perl_free(one_perl); PERL_SET_CONTEXT(two_perl); perl_free(two_perl); PERL_SYS_TERM(); exit(EXIT_SUCCESS); }

        Yeah - if you want to use a different variable name, you have to avoid all the macros. I'm not sure if there is a simple way to recognize all those macros (beyond running the compiler). As aTHX and aTHX_ are known, then likely any macro that contains THX (the thread handle, if Perl is compiled with threads, empty otherwise) should be avoided...