Login Register






Thread Rating:
  • 0 Vote(s) - 0 Average


Embedding Perl in C filter_list
Author
Message
Embedding Perl in C #1
Perl is a great scripting language, and an easy one to embed in a C program if you need that kind of functionality.

Before we write any code, we need to setup our build environment. The first thing to do is create a Makefile, and add the following variables to it:
Code:
CFLAGS := -O1 $(shell perl -MExtUtils::Embed -eccopts,ldopts)
CC := $(shell perl -MConfig -e'print $$Config{cc}')
This gets the compiler that Perl is built with on your system, and the options needed to embed Perl using it. The "-O1" flag is to match the optimization level in ldflags.

Next, we add our rules. This is by all means a quick and dirty Makefile, so look up the proper way to do it if you intend to scale this.
Code:
.PHONY: build clean

build: lib/*.c
$(CC) -o embed $< $(CFLAGS)

clean: embed
rm $<
Running "make build" (or just "make" since it's the default) will build our executable, and running "make clean" will delete it.

Now for the code. Create a directory called "lib", open a new file (name doesn't matter, as we used a wildcard for the compiler), and include these headers.
Code:
#include <EXTERN.h> // perl extern
#include <perl.h> // perl API

Next, we define our interpreter instance and create the skeleton of our main function (the name of the interpreter DOES matter, there's a hard-coded referenced in the PERL_SYS_INIT3 macro). And yes, that is a third (legacy) argument passed to main. It's been mostly obsolete since C89 due to getenv(), but it's useful for cases such as these.
Code:
static PerlInterpreter *my_perl;

int main(int argc,char **argv,char **env){
// modify C runtime to run perl
PERL_SYS_INIT3(&argc,&argv,&env);

// rest of main body goes here

// restore C runtime
PERL_SYS_TERM();
return 0;
}

Now we can create the interpreter instance and run our program:
Code:
int main(int argc,char **argv,char **env){
// ...

// allocate for and create interpreter
my_perl=perl_alloc();
perl_construct(my_perl);

// add exit flags
PL_exit_flags|=PERL_EXIT_DESTRUCT_END;

// parse and interpret script
perl_parse(my_perl,NULL,argc,argv,(char**) NULL);
perl_run(my_perl);

// ...
}

Finally, we need to add a bit more to the cleanup section. Before the PERL_SYS_TERM() macro call, add the following to free any created instances.
Code:
int main(int argc,char **argv,char **env){
// ...

// destroy interpreter and free heap
perl_destroy(my_perl);
perl_free(my_perl);

// restore C runtime
PERL_SYS_TERM();
return 0;
}

Now we can build our program and pipe or redirect input to it, or provide a file to run.
Code:
$ make
...
$ cat hello.pl | ./embed
Hello, world!
$ ./embed <<< $(cat hello.pl)
Hello, world!
$ ./embed hello.pl
Hello, world!
It's often the outcasts, the iconoclasts ... those who have the least to lose because they
don't have much in the first place, who feel the new currents and ride them the farthest.

Reply

RE: Embedding Perl in C #2
Seems cool. I was looking for a language to embed in a project that I'm working on, but didn't even think of Perl. I'll look into it more


(11-02-2018, 02:51 AM)Skullmeat Wrote: Ok, there no real practical reason for doing this, but that's never stopped me.

Reply

RE: Embedding Perl in C #3
(01-25-2018, 06:25 PM)Ender Wrote: Seems cool.  I was looking for a language to embed in a project that I'm working on, but didn't even think of Perl.  I'll look into it more

Obviously there's more you can do than just run scripts. For the full functionality check "man perlembed" or this link.
It's often the outcasts, the iconoclasts ... those who have the least to lose because they
don't have much in the first place, who feel the new currents and ride them the farthest.

Reply

RE: Embedding Perl in C #4
Correct me if I am wrong, but couldn't you just do a system call to Perl and then parse the result of that?

Reply

RE: Embedding Perl in C #5
(02-09-2018, 08:32 PM)Confidential Wrote: Correct me if I am wrong, but couldn't you just do a system call to Perl and then parse the result of that?

If you're embedding Perl as a runtime API for a framework, for example, you'll likely need more than just the output of the script. The docs and man pages show ways of running functions in the script and retrieving variables, among other things.

Docs: https://perldoc.perl.org/perlembed.html
It's often the outcasts, the iconoclasts ... those who have the least to lose because they
don't have much in the first place, who feel the new currents and ride them the farthest.

Reply

RE: Embedding Perl in C #6
Thank you for this very nice job

Reply

RE: Embedding Perl in C #7
(02-10-2018, 05:17 AM)Valkyrie Wrote:
(02-09-2018, 08:32 PM)Confidential Wrote: Correct me if I am wrong, but couldn't you just do a system call to Perl and then parse the result of that?

If you're embedding Perl as a runtime API for a framework, for example, you'll likely need more than just the output of the script. The docs and man pages show ways of running functions in the script and retrieving variables, among other things.

Docs: https://perldoc.perl.org/perlembed.html

Ah, I see. Thanks for enlightening me.

Reply







Users browsing this thread: 1 Guest(s)