Mailing List Archive

To embed or not to embed, that is the question.
Hi. I am writing an app in C, part of which is ideally suited to being
written in Perl as it basically involves file transformation. The
question is, is it worth trying to embed the Perl interpreter inside my
app, or is it simpler just to fork & exec perl? The perlembed man page
is a bit thin, to say the least!

Alan Burlison aburlison@cix.compulink.co.uk
Re: To embed or not to embed, that is the question. [ In reply to ]
: Hi. I am writing an app in C, part of which is ideally suited to being
: written in Perl as it basically involves file transformation. The
: question is, is it worth trying to embed the Perl interpreter inside my
: app, or is it simpler just to fork & exec perl? The perlembed man page
: is a bit thin, to say the least!

My decision to embed was based mostly on the amount of data
interaction between the C side and the Perl side. If you do a fork
and exec, you're stuck with having to convert from data (C side) to
data stream to data (Perl) to converted data (Perl) to data stream to
converted data (C side). You also have to deal with the asynchronous
nature of the transfer method (be it sockets or other), which I've
always found to be a major pain. I haven't measured it, but my gut
feeling is that if you have a *lot* of data to convert, the need to
transfer all the data back and forth becomes a major bottleneck.

With embedding, you get data to SV to converted SV to converted data,
which is likely to be much faster. Of course, that's just my opinion,
I could be wrong. :-)

Of course, if the C side isn't very extensive, you might be able to
embed it in Perl via the XSub mechanism, which would accomplish the
same thing.


William
Re: To embed or not to embed, that is the question. [ In reply to ]
: Hi. I am writing an app in C, part of which is ideally suited to being
: written in Perl as it basically involves file transformation. The
: question is, is it worth trying to embed the Perl interpreter inside my
: app, or is it simpler just to fork & exec perl? The perlembed man page
: is a bit thin, to say the least!

Along with what William said, let me pass along something I wrote a
while back. Hopefully this will make it into perlembed at some point.

Larry

Newsgroups: comp.lang.perl
Path: netlabs!lwall
From: lwall@netlabs.com (Larry Wall)
Subject: Re: perl_parse
Message-ID: <1995Jun5.222825.28046@netlabs.com>
Organization: NetLabs, Inc., Los Altos, California.
References: <3qklk0INNh1j@calvin.lif.icnet.uk> <3qn61n$ipg@news.irisa.fr>
Date: Mon, 5 Jun 1995 22:28:25 GMT
Lines: 64

In article <3qn61n$ipg@news.irisa.fr>, Philippe Bois <bois@irisa.fr> wrote:
:
: Where is the name of the file which contains the script to be parse in the parameters
: of Perl_parse function ?
:
:
: Perl_parse
: ----------
: my_perl : interpreter
: xs_init : DynaLoader
: argc : ?
: argv : ?
: env : ?

It comes in as one of the strings listed in argv. I can't tell you
which one because it depends on how many switches you pass. Just
pretend as though you were calling main() in a C program. So first you
put the (fake) name of the perl executable, then any switches for perl, then
the name of the script, then any arguments to the script. Be sure to
pass the total number of argv elements in argc. It would look something
like this (slightly untested):

PerlInterpreter *my_perl;
static void xs_init _((void));

static char *myargv[] = {
"Foo_perl", /* fake name of executable */
"-w", /* switch to perl interpreter */
"/usr/lib/foo/my_init_script", /* name of script to run */
"-foo", /* switches for script */
"-bar", /* switches for script */
0};

static int myargc = 5;

void init_perl_interpreter()
{
int exitstatus;

my_perl = perl_alloc();
if (!my_perl)
exit(1);
perl_construct( my_perl );

exitstatus = perl_parse( my_perl, xs_init, myargc, myargv, environ );

if (!exitstatus)
exitstatus = perl_run( my_perl ); /* run init script */

if (exitstatus) {
fprintf(stderr, "Couldn't init interpreter, status %d\n", exitstatus);
return;
}

/* After this you can use perl_call_sv(), but be sure to use G_EVAL. */
}

static void
xs_init()
{
char* file = __FILE__;
extern void boot_DynaLoader _((CV* cv));
newXS("DynaLoader::boot_DynaLoader", boot_DynaLoader, file);
}
Re: To embed or not to embed, that is the question. [ In reply to ]
: Hi. I am writing an app in C, part of which is ideally suited to being
: written in Perl as it basically involves file transformation. The
: question is, is it worth trying to embed the Perl interpreter inside my
: app, or is it simpler just to fork & exec perl? The perlembed man page
: is a bit thin, to say the least!

Along with what William said, let me pass along something I wrote a
while back. Hopefully this will make it into perlembed at some point.

Larry

Newsgroups: comp.lang.perl
Path: netlabs!lwall
From: lwall@netlabs.com (Larry Wall)
Subject: Re: perl_parse
Message-ID: <1995Jun5.222825.28046@netlabs.com>
Organization: NetLabs, Inc., Los Altos, California.
References: <3qklk0INNh1j@calvin.lif.icnet.uk> <3qn61n$ipg@news.irisa.fr>
Date: Mon, 5 Jun 1995 22:28:25 GMT
Lines: 64

In article <3qn61n$ipg@news.irisa.fr>, Philippe Bois <bois@irisa.fr> wrote:
:
: Where is the name of the file which contains the script to be parse in the parameters
: of Perl_parse function ?
:
:
: Perl_parse
: ----------
: my_perl : interpreter
: xs_init : DynaLoader
: argc : ?
: argv : ?
: env : ?

It comes in as one of the strings listed in argv. I can't tell you
which one because it depends on how many switches you pass. Just
pretend as though you were calling main() in a C program. So first you
put the (fake) name of the perl executable, then any switches for perl, then
the name of the script, then any arguments to the script. Be sure to
pass the total number of argv elements in argc. It would look something
like this (slightly untested):

PerlInterpreter *my_perl;
static void xs_init _((void));

static char *myargv[] = {
"Foo_perl", /* fake name of executable */
"-w", /* switch to perl interpreter */
"/usr/lib/foo/my_init_script", /* name of script to run */
"-foo", /* switches for script */
"-bar", /* switches for script */
0};

static int myargc = 5;

void init_perl_interpreter()
{
int exitstatus;

my_perl = perl_alloc();
if (!my_perl)
exit(1);
perl_construct( my_perl );

exitstatus = perl_parse( my_perl, xs_init, myargc, myargv, environ );

if (!exitstatus)
exitstatus = perl_run( my_perl ); /* run init script */

if (exitstatus) {
fprintf(stderr, "Couldn't init interpreter, status %d\n", exitstatus);
return;
}

/* After this you can use perl_call_sv(), but be sure to use G_EVAL. */
}

static void
xs_init()
{
char* file = __FILE__;
extern void boot_DynaLoader _((CV* cv));
newXS("DynaLoader::boot_DynaLoader", boot_DynaLoader, file);
}