Beefy Boxes and Bandwidth Generously Provided by pair Networks
No such thing as a small change

Extending an embedded Perl interpreter without a .pm file

by ShodadVenturi (Acolyte)
on Feb 07, 2005 at 22:00 UTC ( #428832=perlquestion: print w/replies, xml ) Need Help??
ShodadVenturi has asked for the wisdom of the Perl Monks concerning the following question:

Okay, I have a C application that needs to execute fragments of Perl script provided by the user.

I have successfully embedded the Perl interpreter, and it is working great. The next step is to provide the ability for the user to make calls into my C program to get certain information, take certain actions, etc. I have written an extension using SWIG, and built that into my program as well. After constructing my perl interpreter, with the appropriate xs_init function that adds my DynTrans as a static XSUB, I immediately use:

eval_pv("use DynTrans;", FALSE);
To get my custom functions into the perl interpreter's namespace. This all works correctly, and I can call into my C program from the Perl script.

So, the problem: In order for this to work, I have to have in the directory where I run my application. I want to remove this requirement, I want the entire application to be completely self-contained. I have gone so far as to modify my code like this:

perl_setup_module(); eval_pv("use DynTrans;", FALSE); perl_cleanup_module();

The perl_setup_module creates the file, and the perl_cleanup_module deletes it, and this also works. However I don't like the fact of needing to drop a temporary file on the user's filesystem.

So, the question: Is there a way that I can make XSUBs availiable to my perl interpreter without having to have the .pm file around at all?
I tried building the entire .pm file into my application with a series of eval_pv() for every line, but of course that didn't work.

What I would really like is a programatic interface into whatever the use DynTrans; perl stuff does. I have read and re-read perlembed, perlxs, perlguts, perlapi, perlcall, several perl books, forums, SuperSearch, etc. and I cannot find a way to do this.

Can anyone save me from the dreaded .pm file? Thanks in advance.

Replies are listed 'Best First'.
Re: Extending an embedded Perl interpreter without a .pm file
by jeremyh (Beadle) on Feb 08, 2005 at 00:07 UTC
    I have embedded the perl interpreter in a C app and used
    perl_parse(my_perl, argc, argv, env);
    perl_parse(my_perl, xs_init, argc, argv, env);

    where argv[1] = ""; argv[0] = c program's argv[0];

    then I do the "use My_Module;"

    in (it's just a wrapper for the module call)

    You can set up @INC in so that you can be sure to find your module.

    I have not used a full path for, but I'm pretty sure you could.

      So I suppose you could put your functions directly in and dispense with the .pm file.
Re: Extending an embedded Perl interpreter without a .pm file
by jeremyh (Beadle) on Feb 08, 2005 at 00:56 UTC
    Have you tried putting all the code for "DynTrans" in the first argument to eval_pv, but just as a perl script containing subroutines, not as a Package?
      The problem with this is that the code that I want to add is written in C, not Perl. So I need the package to interface the C implementations into Perl callables. It's not just a matter of making these subroutines visible to Perl, but also linking them to the correct C functions. I assume that the .pm file is doing this somehow, but I don't know what the context is, it doesn't seem to be in the main namespace of the interpreter, or the eval_pv() trick described above would have worked.

      Thanks for the suggestions, though.

Re: Extending an embedded Perl interpreter without a .pm file
by chromatic (Archbishop) on Feb 07, 2005 at 22:59 UTC

    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.

      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.
Re: Extending an embedded Perl interpreter without a .pm file
by sth (Priest) on Feb 08, 2005 at 20:09 UTC

    I would post this to the Perl-Xs list. List is low traffic, but you will get some good suggestions.

Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://428832]
Approved by Corion
Front-paged by Old_Gray_Bear
and all is quiet...

How do I use this? | Other CB clients
Other Users?
Others chanting in the Monastery: (8)
As of 2017-02-26 04:19 GMT
Find Nodes?
    Voting Booth?
    Before electricity was invented, what was the Electric Eel called?

    Results (371 votes). Check out past polls.