Beefy Boxes and Bandwidth Generously Provided by pair Networks
Do you know where your variables are?
 
PerlMonks  

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

by sciurius (Sexton)
on May 06, 2020 at 12:17 UTC ( [id://11116505]=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?

https://perldoc.perl.org/perlembed.html#Using-Perl-modules%2c-which-themselves-use-C-libraries%2c-from-your-C-program

If I don't setup the DynaLoader like this I get errors like this (IRL, not in the sample):

Can't load module Encode, dynamic loading not available in this perl. (You may need to build a new perl executable which either supports dynamic loading or has the Encode module statically linked into it.) at Encode.pm line 13.

Replies are listed 'Best First'.
Re^3: How to setup the DynaLoader in a dynamically loaded perl?
by sciurius (Sexton) on May 07, 2020 at 17:34 UTC
    Finally got it all up and running.

    One of the additional steps that were needed was to rename the so-name of the library in all .so files.

    For this I used the patchelf tool:

    cp -pL ${PERLLIB}/libperl.so ${DEST}/${PERLSO} cp -pL ${PERLLIB}/libpthread.so.0 ${DEST}/ patchelf --set-soname perl530.so ${DEST}/${PERLSO} find ${DEST} -name '*.so' -exec patchelf --replace-needed libperl. +so.5.30 ${PERLSO} {} \;
    The resultant, and working, program is now:
    #include <stdio.h> #include <stdlib.h> #include <dlfcn.h> #include <EXTERN.h> #include <perl.h> void *handle; /* for dl */ #ifndef PERLSO # define PERLSO "perl530.so" #endif static pTHX; void xs_init(pTHX); int main( int argc, char **argv, char **env ) { /* Assuming the program binary /foo/bar/blech */ char selfpath[PATH_MAX]; /* /foo/bar */ char scriptname[PATH_MAX]; /* blech */ char dllpath[PATH_MAX]; /* /foo/bar/PERLSO */ memset (selfpath, 0, PATH_MAX); memset (scriptname, 0, PATH_MAX); memset (dllpath, 0, PATH_MAX); if ( readlink ("/proc/self/exe", selfpath, PATH_MAX-1 ) > 0 ) { char *p = rindex( selfpath, '/' ); if ( p ) { p++; strcpy( scriptname, p ); *p = 0; } else strcpy( scriptname, selfpath ); #ifdef DEBUG fprintf( stderr, "selfpath: %s\n", selfpath ); fprintf( stderr, "scriptname: %s\n", scriptname ); #endif } else { strncpy( selfpath, argv[0], PATH_MAX-1 ); char *p = rindex( selfpath, '/' ); if ( p ) { p++; strcpy( scriptname, p ); *p = 0; } else { p = getcwd( selfpath, PATH_MAX-1 ); strcat( selfpath, "/" ); strncpy( scriptname, argv[0], PATH_MAX-1 ); } #ifdef DEBUG fprintf( stderr, "cwdpath: %s\n", selfpath ); fprintf( stderr, "scriptname: %s\n", scriptname ); #endif } /* Open shared lib. */ strcpy( dllpath, selfpath ); strcat( dllpath, PERLSO ); #ifdef DEBUG fprintf( stderr, "dllpath: %s\n", dllpath ); #endif handle = dlopen( dllpath, RTLD_LAZY ); if ( !handle ) { fprintf( stderr, "%s\n", dlerror() ); exit(EXIT_FAILURE); } /* Start perl environment. */ //PERL_SYS_INIT3( &argc, &argv, &env ); void (*Perl_sys_init3)( int*, char***, char*** ); Perl_sys_init3 = (void(*)(int*, char***, char***)) dlsym(handle, "Pe +rl_sys_init3"); (*Perl_sys_init3)(&argc, &argv, &env); /* Create a perl interpreter. */ tTHX (*perl_alloc)(); perl_alloc = (tTHX(*)()) dlsym(handle, "perl_alloc"); my_perl = (*perl_alloc)(); /* perl_construct */ void (*perl_construct)(pTHX); perl_construct = (void(*)(pTHX)) dlsym(handle, "perl_construct"); (*perl_construct)(aTHX); /* perl_parse */ void (*perl_parse)(pTHX, void*, int, char**, char**); perl_parse = (void(*)(pTHX, void*, int, char**, char**)) dlsym(handl +e, "perl_parse"); /* If we're "perl", behave like perl. */ if ( !strncmp( scriptname, "perl", 4 ) ) (*perl_parse)( aTHX, xs_init, argc, argv, env ); else { /* Insert script name in argv. */ char scriptpath[PATH_MAX]; /* /foo/bar/SCRIPTPREFIXblech.pl */ strcpy( scriptpath, selfpath ); #ifdef SCRIPTPREFIX strcat( scriptpath, "script/" ); #endif strcat( scriptpath, scriptname ); strcat( scriptpath, ".pl" ); /* To get @INC right we execute it as a -E script. */ char cmd[2*PATH_MAX+100]; sprintf( cmd, "@INC=(q{%slib});do q{%s};", selfpath, scriptpath ); #ifdef DEBUG fprintf( stderr, "scriptpath: %s\n", scriptpath ); fprintf( stderr, "cmd: %s\n", cmd ); #endif # define EXTRA_ARGS 3 char **ourargv = (char **)calloc( argc+1+EXTRA_ARGS, sizeof(char** +) ); ourargv[0] = argv[0]; ourargv[1] = "-E"; ourargv[2] = cmd; ourargv[3] = "--"; for ( int i=1; i<=argc; ++i ) { ourargv[i+EXTRA_ARGS] = argv[i]; } (*perl_parse)(aTHX, xs_init, argc+EXTRA_ARGS, ourargv, env); } /* Set @INC to just our stuff. But it's too late. */ // char cmd[PATH_MAX+100]; // sprintf( cmd, "@INC = (q{%slib});", selfpath ); // SV* (*eval_pv)(pTHX, const char*, I32); // eval_pv = (SV* (*)(pTHX, const char*, I32)) dlsym( handle, "Perl +_eval_pv" ); // (*eval_pv)( aTHX, cmd, TRUE ); /* Run... */ int (*perl_run)(pTHX); perl_run = (int(*)(pTHX)) dlsym(handle, "perl_run"); int result = (*perl_run)(aTHX); /* Cleanup. */ void(*perl_destruct)(pTHX); perl_destruct = (void(*)(pTHX)) dlsym(handle, "perl_destruct"); (*perl_destruct)(aTHX); void(*perl_free)(pTHX); perl_free = (void(*)(pTHX)) dlsym(handle, "perl_free"); (*perl_free)(aTHX); return result; } void (*boot_DynaLoader_dyn)(pTHX, CV* cv); CV* (*Perl_newXS_dyn)(pTHX, const char*, XSUBADDR_t, const char*); void xs_init(pTHX) { static const char file[] = __FILE__; // dXSUB_SYS; /* dNOOP */ // PERL_UNUSED_CONTEXT; /* boot_DynaLoader */ boot_DynaLoader_dyn = (void (*)(pTHX, CV* cv)) dlsym(handle, "boot +_DynaLoader"); if ( !boot_DynaLoader_dyn ) { fprintf( stderr, "(boot_DynaLoader) %s\n", dlerror() ); exit(EXIT_FAILURE); } /* newXS is just Perl_newXS(aTHX, ...) */ Perl_newXS_dyn = (CV* (*)(pTHX, const char*, XSUBADDR_t, const cha +r*)) dlsym( handle, "Perl_newXS" ); /* The following comment is mandatory. */ /* DynaLoader is a special case */ (*Perl_newXS_dyn)( aTHX, "DynaLoader::boot_DynaLoader", *boot_Dyna +Loader_dyn, file ); }

    Thanks for your help!

Log In?
Username:
Password:

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

How do I use this?Last hourOther CB clients
Other Users?
Others making s'mores by the fire in the courtyard of the Monastery: (7)
As of 2024-04-25 14:30 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found