in reply to Extending an embedded Perl interpreter without a .pm file

What happens if you put the whole text of the module in a single string and pass that to eval_pv()? I haven't tried, but I don't see any reason why that shouldn't work.

Replies are listed 'Best First'.
Re^2: Extending an embedded Perl interpreter without a .pm file
by ShodadVenturi (Acolyte) on Feb 07, 2005 at 23:19 UTC
    I tried that, and while I did not get an error message, I also did not get my custom functions. The empty result was the same as when I didn't have the .pm file in the directory where the program started.

    It seems that Perl isn't executing the .pm file directly as Perl code, at least not in the main interpreter namespace, but is rather pulling it in as part of the module loading/initialization process. I.E. the eval_pv() method that I tried would be akin to writing a perl script and beginning it with: (this is the .pm file that SWIG generated)

    package DynTrans; require Exporter; @ISA = qw(Exporter); package DynTrans; boot_DynTrans(); package DynTrans; @EXPORT = qw( GetTableName GetAction ); . . . User script here ...
    This wouldn't work, because we aren't trying to define the DynTrans package in the perl script, but rather we want to use DynTrans; to do other work.

    Does this make sense?

      One clarification, I did the eval_pv() thing using one big string that contained the entire contents of the .pm file that I was trying to get rid of. That didn't work so I next did it as series of eval_pv() calls, one per line of the .pm file. That didn't work, either. Both cases the results were as described above.

        How about eval_pv'ing a string containing the contents of the file, plus "DynTrans->import;"? use DynTrans; is roughly equivalent to BEGIN { require DynTrans; DynTrans->import; }. eval_pv'ing the contents of DynTrans.pm is like require-ing it. Add a "package main;", before the import, and voila!

        Tested this, and it works:

        Key lines:

        /* moduletext = text of module + "package main; DynTrans->import;" */ eval_pv(moduletext, TRUE); /* ~ use DynTrans; */ eval_pv("$a = fortytwo();", TRUE); /* its function is available */

        Full C source

        #include <EXTERN.h> #include <perl.h> static PerlInterpreter *pi; /* Note the last two lines "package main; DynTrans->import" */ static char *moduletext = "package DynTrans;\n\ use base qw/Exporter/;\n\ our @EXPORT;\n\ BEGIN { @EXPORT = qw/&fortytwo/; }\n\ sub fortytwo { 42; }\n\ 1;\n\ package main;\n\ DynTrans->import;"; int main(int argc, char **argv, char **env) { STRLEN n_a; char *embedding[] = { "", "-e", "0" }; pi = perl_alloc(); perl_construct(pi); perl_parse(pi, NULL, 3, embedding, NULL); PL_exit_flags |= PERL_EXIT_DESTRUCT_END; perl_run(pi); eval_pv(moduletext, TRUE); /* ~ use DynTrans; */ eval_pv("$a = fortytwo();", TRUE); /* its function is available */ printf("EXPECT: a = 42\nGOT: a = %d\n", SvIV(get_sv("a", FALSE) +)); perl_destruct(pi); perl_free(pi); return 0; }
        OUTPUT: EXPECT: a = 42 GOT: a = 42