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

Hey monks, I'm working on a Lua-Perl bridge, and I've hit a snag on the way. Basically, I'm writing a dynamically-loadable module for Lua that allows Lua to evaluate Perl expressions (later on, I hope for it to be able to exchange data between the two environments seamlessly). Things work fine until I evaluate something like use Scalar::Util, which results in the following error (I'm on Fedora 12, 64-bit):

Can't load '/usr/lib64/perl5/5.10.0/x86_64-linux-thread-multi/auto/B/B +.so' for module B: /usr/lib64/perl5/5.10.0/x86_64-linux-thread-multi/auto/B/B.so: undefin +ed symbol: PL_opargs at /usr/lib64/perl5/5.10.0/x86_64-linux-thread-m +ulti/XSLoader.pm line 64. at /usr/lib64/perl5/5.10.0/x86_64-linux-thread-multi/B.pm line 316

I checked out the "Using Perl modules, which themselves use C libraries, from your C program" section of perlembed, but it didn't have much to say on this kind of error. However, if I build a custom Lua interpreter with my module statically linked into it, use Scalar::Util works without a problem. I understand the basics of linking, but when a dlopen'd module is linked to a shared object that dlopens other modules...that's when I get confused.

In the interest of getting a good response, I've created a sample program that replicates this error, sans Lua. The source is available here:

http://hoelzro.net/public/perl-test.tar.gz

If you extract the archive and run make, it'll create two executables: test-static and test-dynamic. Running test-static should just print Scalar::Util's version. Running test-dynamic will print an error message similar to the one above, along with Scalar::Util's version.

I would appreciate any and all help you would be able to give me!

Thanks,
Rob

Replies are listed 'Best First'.
Re: Perl embedding woes: undefined symbols
by ikegami (Pope) on Apr 29, 2010 at 19:53 UTC
    You'd need this:
    EXTERN_C void boot_DynaLoader(pTHX_ CV* cv); EXTERN_C void boot_List__Util(pTHX_ CV* cv); static void xs_init(pTHX) { char *file = __FILE__; newXS("DynaLoader::boot_DynaLoader", boot_DynaLoader, file); newXS("List::Util::bootstrap", boot_List__Util, file); }

    (Scalar::Util's C guts are actually loaded by List::Util.)

    Now, there's still the matter of linking in ListUtil.o. I don't know how to do that (other than statically linking it into Perl).

      I figured I could do that, but I'd rather the users of the Lua-Perl bridge not have to recompile the module every time they want to use an XS module.
        So they have to have Perl installed locally, then. If so, why not just run Perl as a child?
Re: Perl embedding woes: undefined symbols
by Fletch (Chancellor) on Apr 29, 2010 at 19:25 UTC

    Not exactly your problem, but . . . Inline::Lua?

    Update: Duur. Me misread.

    The cake is a lie.
    The cake is a lie.
    The cake is a lie.

      I know of Inline::Lua, but unfortunately that's going in the opposite direction. =/
Re: Perl embedding woes: undefined symbols
by robhoelz (Acolyte) on May 04, 2010 at 21:38 UTC
    Problem solved! I solved the problem by creating a dummy .so that links to -lperl, and I load that using RTLD_GLOBAL in my module's initialization.
Re: Perl embedding woes: undefined symbols
by robhoelz (Acolyte) on May 04, 2010 at 14:32 UTC
    Hey monks, status update for you: I managed to get my example to work this morning by adding RTLD_GLOBAL to the list of flags I provide to dlopen. Now it's just a matter of getting Lua to do the same!