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

Esteemed Monks,

How can we use the Perl API in C programs? I'm sure I did something very wrong. For example:
#include "EXTERN.h" #include "perl.h" #include "XSUB.h" int main() { AV* list; list = newAV(); av_push(list,newSViv(5)); I32 n = av_len(list); printf("d%\n",n); return 1; }
This code compiles and links with no problems but when executed seg faults (when newAV() called).

You may ask why I want to do this. Well, it's just experimentation. Actually, let ask you the same question. Can the Perl-API be helpful to C programmers? Any experiences?
Thanks!

Replies are listed 'Best First'.
Re: Perl API with C
by kvale (Monsignor) on Apr 17, 2004 at 19:46 UTC
    You are missing a perl interpreter.

    To learn how to embed perl in your C program, check out perlembed. Here is interp.c from the 5.8.0 docs:

    #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) { 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); }
    This would then be compiled with a statement like
    % cc -o interp interp.c `perl -MExtUtils::Embed -e ccopts -e ldopts`
    It is a bit of a learning curve to figure all this out, but people have embedded perl in their C programs as a built-in scripting language. It is less popular than one might think, however, because it is so easy for perl to interact with standalone C programs.

    -Mark

      Thanks kvale, but I don't want to embed anything, I just want to use Perl API's C functions within a C program (if it's possible). :))
        Au contraire. You do want to embed something - a Perl interpreter!

        The Perl API is an interface between C and a Perl interpreter. For instance when you try to create a newAV, you needs to AvALLOC it, which allocation assumes that some memory arenas have already been initialized and exist so that you have somewhere to allocate the basic data structure. Which is something that a Perl interpreter does when you start it up. Without a Perl interpreter you are going to do something silly like trying to follow an unitialized value of PL_sv_root and crash after following a null pointer.

        So you can either figure out everything that a Perl interpreter initializes coming into existence (which is basically constructing a Perl interpreter by hand, and WILL break between releases of Perl), or else you can create a Perl interpreter.

        Now hie thee to perlembed as suggested. And note that the first section is about who needs to read perlembed. Given what you are doing, it is appropriate for you.