Questions about "perldoc perlembed"

Do you have a question? Post it now! No Registration Necessary.  Now with pictures!

Threaded View

   Ultimately I am trying to embed the ability to run Perl scripts on
a C++ program written in Visual Studio 2005 (on a Windows XP
machine).  I have read "perldoc perlembed" and I have followed along
by running several of its examples on a Linux platform.  While I can
get the sample programs to work on Linux, I am stumbling on getting
Perl to properly embed in my Win32 C++ program.

   So I have a bunch of questions to ask about some of the concepts in
"perlembed".  I'm hoping that with the answers to my questions I might
be able to resolve my issues.

Issue 1:  "perlembed" gives the following warning:

   If you have trouble compiling the scripts in this
   documentation, you're not alone. The cardinal rule:
   WAY THAT YOUR PERL WAS COMPILED. (Sorry for yelling.)

Now, I was able to compile Perl by downloading from
ActiveState, unzipping it, cd-ing to perl/win32 and typing "nmake".
What confuses me is that this is not the same way I compile my main C+
+ program.  In Visual Studio, I normally load a *.sln or *.vcproj file
and compile it from there, never using nmake or a Unix-like Makefile.
Therefore, I can't quite figure out how to compile both perl and my C+
+ program with the same options.

So question 1 is:  How do I compile both Perl and my C++ program "in
exactly the same way"?

Issue 2:  "perlembed" gives a wonderful example program that
demonstrates how to run/evaluate Perl statements from a C program
(header comments are mine):
/* From "perldoc perlembed" */
/* Compile on Unix with:
    cc -o perl_eg1 perl_eg1.c `perl -MExtUtils::Embed -e ccopts -e

#include <EXTERN.h>
#include <perl.h>

static PerlInterpreter *my_perl;

main (int argc, char **argv, char **env)
    STRLEN n_a;
    char *embedding[] = { "", "-e", "0" };

    my_perl = perl_alloc();
    perl_construct( my_perl );

    perl_parse(my_perl, NULL, 3, embedding, NULL);
    PL_exit_flags |= PERL_EXIT_DESTRUCT_END;

    /** Treat $a as an integer **/
    eval_pv("$a = 3; $a **= 2", TRUE);
    printf("a = %d\n", SvIV(get_sv("a", FALSE)));

    /** Treat $a as a float **/
    eval_pv("$a = 3.14; $a **= 2", TRUE);
    printf("a = %f\n", SvNV(get_sv("a", FALSE)));

    /** Treat $a as a string **/
    eval_pv("$a = 'rekcaH lreP rehtonA tsuJ'; $a = reverse($a);",
    printf("a = %s\n", SvPV(get_sv("a", FALSE), n_a));


I was curious to see how calls to eval_pv() knew which PerlInterpreter
to use, so I changed all instances of "my_perl" to "my__perl" (note
the double underscores).  But when I tried to compile the program, I
got the following compiler error:

perl_eg1.c: In function `main':
perl_eg1.c:21: error: `my_perl' undeclared

I thought that was odd... Of course 'my_perl' is undeclared -- it's
'my__perl' that I want it to use.  But for some reason, the
"PL_exit_flags |= PERL_EXIT_DESTRUCT_END;" line wants to use
'my_perl', whether it was declared or not.  (Incidentally, I tried
commenting out that line to see what would happen, and the compiler
gave the same complaint for line 25, which is the ' eval_pv("$a = 3;
$a **= 2", TRUE);' line.)

So evidently, PL_exit_flags and eval_pv() want to use a
PerlInterpreter named "my_perl".  But declaring a static/global
variable like in the given example won't work too well with threads,
if I ever have to run two (or more) scripts concurrently.  So I
thought about how to get around this "my_perl" naming requirement.

Eventually I read the section "Maintaining multiple interpreter
instances" (also in "perlembed") which talks about
PERL_SET_CONTEXT().  It says that that call is "necessary to
initialize the global state that tracks which interpreter is the
'current' one on the particular process or thread that may be running

Sounds good.  It seems like I all have to do is call
PERL_SET_CONTEXT(my__perl) for the compiler to stop looking for
"my_perl".  So I put "PERL_SET_CONTEXT(my__perl);" line right before
the perl_construct(), perl_parse(), PL_exit_flags, and all the
eval_pv() lines, but it doesn't appear to do any good.  The compiler
still complains that "my_perl" in undeclared at the PL_exit_flags and
eval_pv() lines.

So question 2 is:  Can calls to eval_pv() only be done when the
PerlInterpreter is specifically named "my_perl"?  (And if not, how can
I specify a differently-named PerlInterpreter?)

Issue 3:  I'm actually able to get a simple Perl program to run from
my C++ program with the following code:

void runPerlScript(char * script_filename)
  char* argv[] = { "PROGRAM_NAME" };
  int argc = sizeof(argv) / sizeof(char*);

  PerlInterpreter *perlInterpreter = perl_alloc();

  char* scriptArguments[] = { "PROGRAM_NAME",
                              script_filename };
  const int numArguments = sizeof(scriptArguments) / sizeof(char*);

  PERL_SET_CONTEXT(perlInterpreter);  // is this line needed?
  PL_perl_destruct_level = 1;

  const int parseResult = perl_parse(perlInterpreter, NULL,
          numArguments, scriptArguments, (char**) NULL);
  if (parseResult == 0)



With this code, I can run a simple script whose filename is passed in
as script_filename.  However, it only succeeds once.  The second time
this function is called, it crashes at the call to perl_parse().

I couldn't figure out what was causing this crash, but I read
something that seemed useful (again in "perlembed"), which said:

   Even if you don't intend to run two or more interpreters
   at the same time, but to run them sequentially, like
   in the above example, it is recommended to build perl
   with the -Dusemultiplicity option otherwise some
   interpreter variables may not be initialized correctly
   between consecutive runs and your application may

Sounds like my problem!  So I go over to the perl/win32 directory and
have a look at its Makefile.  Inside it I see the following lines:

# uncomment to enable multiple interpreters.  This is need
# for fork() emulation and for thread support.
USE_MULTI    = define

and the lines:

CFG_VARS    =                    \
        "INST_DRV=$(INST_DRV)"            \
        "usemultiplicity=$(USE_MULTI)"        \

As far as I can tell, the "usemultiplicity" option is indeed being
used when compiling.  Because of this, I can't figure out why the
second call to perl_parse() is crashing.

So Question 3 is:  Why is my C++ program crashing the second time it
calls perl_parse()?  (Is it because the -Dusemultiplicity option
wasn't set correctly, and if so, how do I set it correctly?)

Issue 4:  I am able to "use" certain simple modules in my Perl scripts
that are run from the C++ program (like "warnigns" and "Time::Local"),
but not ones that have dynamic loading (like "Data::Dumper").  There
is a section in "perldoc perlembed" that addresses this very issue,
and it provides this sample solution for "use"ing the Socket module:

static void xs_init (pTHX);

EXTERN_C void boot_DynaLoader (pTHX_ CV* cv);
EXTERN_C void boot_Socket (pTHX_ CV* cv);

       char *file = __FILE__;
       /* DynaLoader is a special case */
       newXS("DynaLoader::boot_DynaLoader", boot_DynaLoader, file);
       newXS("Socket::bootstrap", boot_Socket, file);

So Question 4a is:  That's nice for Socket, but how would I
incorporate a module name with "::" in it, like "Data::Dumper"?  I
can't just add the line:

   newXS("Data::Dumper::bootstrap", boot_Data::Dumper, file);

I would think that the "::" (outside of the string) would cause a
compiler error.

And Question 4b is:  Do I have to hard-code the inclusion of every
dynamic module I would ever want to use?  (Since the example does it
for the Socket module, it seems as though I would have to.)

   Thanks in advance for any help.

   -- Jean-Luc

Re: Questions about "perldoc perlembed"

Quoted text here. Click to load it

Good luck... this stuff is Not Easy.

Quoted text here. Click to load it

Your comment below says how: use ExtUtils::Embed. If you are using
ActivePerl sources, be very sure that VC++ is the only compiler in your
PATH: ActivePerl patch to emit gcc syntax if gcc is in your
PATH. Also, make sure you are picking up the correct perl5*.dll: the
binary builds of AS Perl are built with MSVC6, and attempting to link
these with MSVC 2005 will cause C library runtime failures.

You need to pass the output of

    perl -MExtUtils::Embed -eccopts

to the 'cc -c' or equivalent ('cl /c'? I can't remember MSVC command-
line syntax) command, and the output of

    perl -MExtUtils::Embed -eldopts

to the link command. Somewhere in the VC gui there should be an option
to allow you to pass custom flags to the compiler and linker.

Also note that if you're compiling just one file, say test.c, then the
ccopts need to come *before* and the ldopts *after* test.c on the

Quoted text here. Click to load it
Quoted text here. Click to load it

Yup. If you root around in intrpvar.h and proto.h you'll find both
PL_exit_flags and eval_pv are #defined to expressions that include

Quoted text here. Click to load it

The simple answer is 'yes'. The most obvious way round it is to notice
what eval_pv expands to: in a perl built with MULTIPLICITY, it is
#defined (in embed.h) with

    #define eval_pv(a,b) Perl_eval_pv(aTHX_ a, b)

and aTHX_ is

    #define aTHX_ my_perl,

. So in MULTIPLICITY perls, Perl_eval_pv takes an extra first parameter
which is a PerlInterpreter*, and you can pass your own my__perl instead.

Another option, of course, is to keep a 'my_perl' variable around, and
switch which interpreter it points to.

I don't know if this is the 'correct' answer: you might want to take a
look at what the users of MULTIPLICITY--mod_perl and threads.xs, most
notably--do about it. Or you might want to ask p5p.

Quoted text here. Click to load it

You may only call PERL_SYS_INIT3 once, ever. Call it in main().

Quoted text here. Click to load it

I'm surprised this line compiles. I would have expected all the PL_*
globals to expand to something that referenced 'my_perl'.

Quoted text here. Click to load it

Ditto PERL_SYS_TERM: only call it once, just before program exit.

[-Dusemultiplicity on Win32]
Quoted text here. Click to load it

Yes, all AS Perl builds have both usethreads and usemultiplicity set
(these are the defaults on vanilla Win32 builds anyway).

Quoted text here. Click to load it

I suspect it's the PERL_SYS_ stuff I mentioned above; if
not, then I don't know. Try p5p, and maybe build a debugging perl and
see if you can get a backtrace.

Quoted text here. Click to load it

Yup: you need to convert ':'s into '_'s, so you get boot_Data__Dumper.
Actually, you don't need to do this at all: xs_init only needs to load
bootstrap functions for extensions that are statically linked, which
nowadays is typically only DynaLoader. In any case, if you run

    perl -MExtUtils::Embed -exsinit

it will create a file called perlxsi.c with the appropriate definition
of xs_init in it. Compile that file, link it into your app, and call
xs_init at the right time.

Quoted text here. Click to load it

No, only those linked statically. Since DynaLoader is always linked
statically, nothing else will work if you don't bootstrap DynaLoader;
but once that's there it takes care of all the dynamically-linked

Once upon a time, when systems didn't tend to support dlopen as well as
they do now, it was common to link lots of extensions directly into
perl, which is why perlembed assumes that's what you might be doing.


For the last month, a large number of PSNs in the Arpa[Inter-]net have been
reporting symptoms of congestion ... These reports have been accompanied by an
increasing number of user complaints ... As of June,... the Arpanet contained
47 nodes and 63 links. [ ] *

Site Timeline