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

Hello, I have the following example code:

#include <EXTERN.h> #include <perl.h> static PerlInterpreter *my_perl; void hello () { printf("Hello, world!\n"); } int main (int argc, char **argv, char **env) { PERL_SYS_INIT3(&argc, &argv, &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); PERL_SYS_TERM(); return 0; }

How do I make the "hello" function available to the "my_perl" interpreter?

This case seems to be not covered in documentation.

The closest thing is, probably, to create a separate xs module with a dynamic library and to evaluate "use Separate::Module" statement, exporting necessary subroutines into perl.

Also there is a "newXSproto" function, but I'm not sure how to use it and if it's at all relevant here

Replies are listed 'Best First'.
Re: Call a C function from Perl used from C
by ikegami (Patriarch) on Mar 28, 2011 at 20:12 UTC

    One approach (based on universal.c):

    #include <EXTERN.h> #include <perl.h> #include <XSUB.h> XS(XS_Package_sub_name) { ...[ Get arguments from Perl stack ]... rv = sub_name(arg); ...[ Return values on Perl stack ]... } int main() { static const char file[] = __FILE__; ... newXS("Package::sub_name, XS_Package_sub_name, file); ... }

    The following are equivalent:

    newXS("Package::sub_name, XS_Package_sub_name, file); newXSproto("Package::sub_name, XS_Package_sub_name, file, NULL); newXS_flags("Package::sub_name, XS_Package_sub_name, file, NULL, 0);

    By taking this approach, you have to do everything XS would do for you manually. You will probably have a simpler time handling the arguments if you went the route of an XS module. If you do create an XS module, see "Using Perl modules, which themselves use C libraries, from your C program" in perlembed for how to load it up.

      Wow, thank you for your reply. Here's a working example:
      #include <EXTERN.h> #include <perl.h> #include <XSUB.h> static PerlInterpreter *my_perl; void hello () { printf("Hello, world!\n"); } XS(XS_main_hello) { dXSARGS; if (items != 0) croak_xs_usage(cv, ""); hello(); XSRETURN_EMPTY; } int main (int argc, char **argv, char **env) { static const char file[] = __FILE__; PERL_SYS_INIT3(&argc, &argv, &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); newXS("main::hello", XS_main_hello, file); perl_run(my_perl); perl_destruct(my_perl); perl_free(my_perl); PERL_SYS_TERM(); return 0; }