![]() |
|
Embedding Perl in C - Printable Version +- Sinisterly (https://sinister.ly) +-- Forum: Coding (https://sinister.ly/Forum-Coding) +--- Forum: C, C++, & Obj-C (https://sinister.ly/Forum-C-C-Obj-C) +--- Thread: Embedding Perl in C (/Thread-Embedding-Perl-in-C) |
Embedding Perl in C - Inori - 01-25-2018 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}')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 $<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 APINext, 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!RE: Embedding Perl in C - Blink - 01-25-2018 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 RE: Embedding Perl in C - Inori - 01-25-2018 (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. RE: Embedding Perl in C - Confidential - 02-09-2018 Correct me if I am wrong, but couldn't you just do a system call to Perl and then parse the result of that? RE: Embedding Perl in C - Inori - 02-10-2018 (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 RE: Embedding Perl in C - benken - 02-10-2018 Thank you for this very nice job RE: Embedding Perl in C - Confidential - 02-10-2018 (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? Ah, I see. Thanks for enlightening me. |