Beefy Boxes and Bandwidth Generously Provided by pair Networks
Don't ask to ask, just ask
 
PerlMonks  

Re^2: How to setup the DynaLoader in a dynamically loaded perl?

by sciurius (Sexton)
on May 05, 2020 at 20:00 UTC ( [id://11116488]=note: print w/replies, xml ) Need Help??


in reply to Re: How to setup the DynaLoader in a dynamically loaded perl?
in thread How to setup the DynaLoader in a dynamically loaded perl?

Thanks for your helpful suggestions. Your example compiles and runs, but:
$ ldd aaa linux-vdso.so.1 (0x00007ffd0e4c6000) libperl.so.5.30 => /lib64/libperl.so.5.30 (0x00007fe9264b5000) libpthread.so.0 => /lib64/libpthread.so.0 (0x00007fe926493000) libdl.so.2 => /lib64/libdl.so.2 (0x00007fe92648c000) libc.so.6 => /lib64/libc.so.6 (0x00007fe9262c3000) libm.so.6 => /lib64/libm.so.6 (0x00007fe92617d000) libcrypt.so.2 => /lib64/libcrypt.so.2 (0x00007fe926142000)
So it is already linked to the perl shared library. If I remove -lperl from the link arguments I get:
in function `xs_init': /home/jv/tmp/aaa.c:28: undefined reference to `PL_thr_key' /bin/ld: /home/jv/tmp/aaa.c:28: undefined reference to `pthread_getspe +cific' /bin/ld: /home/jv/tmp/aaa.c:28: undefined reference to `Perl_newXS'
EDIT: Managed to get it going by adding a Perl_newXS function as follows:
CV* Perl_newXS(pTHX_ const char *name, XSUBADDR_t subaddr, const char +*filename) { CV* (*imp)(tTHX, const char*, XSUBADDR_t, const char*); imp = (CV* (*)(tTHX, const char*, XSUBADDR_t, const char*)) dlsym( h +andle, "Perl_newXS" ); return (*imp)(my_perl, name, subaddr, filename); }
The complete proof-of-concept program is now:
#include <stdio.h> #include <stdlib.h> #include <dlfcn.h> #include <EXTERN.h> #include <perl.h> void *handle; /* for dl */ static PerlInterpreter *my_perl; void (*boot_DynaLoader)(pTHX_ CV* cv); CV* Perl_newXS(pTHX_ const char *name, XSUBADDR_t subaddr, const char +*filename) { CV* (*imp)(tTHX, const char*, XSUBADDR_t, const char*); imp = (CV* (*)(tTHX, const char*, XSUBADDR_t, const char*)) dlsym( h +andle, "Perl_newXS" ); return (*imp)(my_perl, name, subaddr, filename); } void xs_init(pTHX) { static const char file[] = __FILE__; dXSUB_SYS; PERL_UNUSED_CONTEXT; newXS( "DynaLoader::boot_DynaLoader", boot_DynaLoader, file ); } int main( int argc, char **argv, char **env ) { /* open shared lib */ handle = dlopen("perl530.so", RTLD_LAZY); if ( !handle ) { fprintf( stderr, "%s\n", dlerror() ); exit(EXIT_FAILURE); } /* Get entry point for perl_alloc */ void* (*perl_alloc)(); perl_alloc = (void*(*)()) dlsym(handle, "perl_alloc"); /* Call perl_alloc */ my_perl = (*perl_alloc)(); /* perl_construct */ void (*perl_construct)(void*); perl_construct = (void(*)(void*)) dlsym(handle, "perl_construct"); (*perl_construct)(my_perl); /* boot_DynaLoader */ boot_DynaLoader = (void (*)(pTHX_ CV* cv)) dlsym(handle, "boot_DynaL +oader"); /* perl_parse */ void (*perl_parse)(void*, void*, int, char**, char**); perl_parse = (void(*)(void*, void*, int, char**, char**)) dlsym(hand +le, "perl_parse"); (*perl_parse)(my_perl, xs_init, argc, argv, env); /* perl_run */ int (*perl_run)(void*); perl_run = (int(*)(void*)) dlsym(handle, "perl_run"); int result = (*perl_run)(my_perl); /* perl_destruct */ void(*perl_destruct)(void*); perl_destruct = (void(*)(void*)) dlsym(handle, "perl_destruct"); (*perl_destruct)(my_perl); /* perl_free */ void(*perl_free)(void*); perl_free = (void(*)(void*)) dlsym(handle, "perl_free"); (*perl_free)(my_perl); return result; }
Build with: $(perl -MConfig -e 'print $Config{cc}') p.c $(perl -MExtUtils::Embed -e ccopts ) -o aaa -ldl -Wl,--rpath=. Although it seems that dynamic loading is not yet functional... For example, this fails:
aaa -MFcntl=:flock -E "say 1+LOCK_NB" Undefined subroutine &Fcntl::LOCK_NB called at -e line 1.

Replies are listed 'Best First'.
Re^3: How to setup the DynaLoader in a dynamically loaded perl?
by bliako (Monsignor) on May 05, 2020 at 21:06 UTC

    As I said, you will need to dlsym anything that you may use later.

    However, when I did this:

    CV* (*Perl_newXS)(pTHX_ const char *name, XSUBADDR_t subaddr, const ch +ar *filename); .... Perl_newXS = (CV* (*)(pTHX_ const char *name, XSUBADDR_t subaddr, cons +t char *filename) )dlsym(handle, "Perl_newXS");

    I got

    error: ‘Perl_newXS’ redeclared as different kind of symbol /usr/lib64/perl5/CORE/proto.h:2517:19: note: previous declaration of ‘ +Perl_newXS’ was here 2517 | PERL_CALLCONV CV* Perl_newXS(pTHX_ const char *name, XSUBADDR_ +t subaddr, const char *filename);

    So, that's a neat trick you have there! (though I would make imp static)

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: note [id://11116488]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others perusing the Monastery: (3)
As of 2024-04-25 10:18 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found