Discussion:
Help in running perl script with arguments within a C code
(too old to reply)
Viresh Kumar
2005-12-13 12:11:25 UTC
Permalink
Hello,

I am facing a problem while running a perl script with arguments within a C
program. The code is as below:

***************************************************************************************
<<file: interp.c>>

#include <EXTERN.h>
#include <perl.h>
static PerlInterpreter *my_perl;

int main(int argc, char **argv, char **env)
{
my_perl = perl_alloc();
perl_construct(my_perl);

char* my_argv[2];
my_argv[0] = "";
my_argv[1] = "test.pl";
int my_argc = 2;
perl_parse(my_perl, xs_init, my_argc, my_argv, (char **)NULL);
perl_run(my_perl);
perl_destruct(my_perl);
perl_free(my_perl);
}

***************************************************************************************

The argument I used is
"-MDevel::Cover=-db,./cover_db"
which i set in the PERL5OPT environment variable.

Now the problem comes is regarding the loading of "Digest::MD5" module which
is used in the coverage module. The following error came:

*Can't load module Digest::MD5, dynamic loading not available in this
perl. (You may need to build a new perl executable which either supports
dynamic loading or has the Digest::MD5 module statically linked into it.)
at /opt/perl_5.8.5/lib/sun4-solaris-thread-multi/Devel/Cover/DB/Structure.pm
line 14
Compilation failed in require at
/opt/perl_5.8.5/lib/sun4-solaris-thread-multi/Devel/Cover/DB/Structure.pm
line 14.
BEGIN failed--compilation aborted at
/opt/perl_5.8.5/lib/sun4-solaris-thread-multi/Devel/Cover/DB/Structure.pm
line 14*

So we inserted the following glue code to make it work:

#ifdef __cplusplus
# define EXTERN_C extern "C"
#else
# define EXTERN_C extern
#endif

static void xs_init _((void));

EXTERN_C void boot_DynaLoader _((CV* cv));
EXTERN_C void boot_Digest _((CV* cv));

EXTERN_C void
xs_init()
{
char *file = __FILE__;
/* DynaLoader is a special case */
newXS("DynaLoader::boot_DynaLoader", boot_DynaLoader, file);
newXS("Digest::bootstrap", boot_Digest, file);
}

I compiled with following command:

gcc -o interp interp.c `perl -MExtUtils::Embed -e ccopts -e ldopts`

I am getting the following error:

*Undefined first referenced
symbol in file
boot_Digest /var/tmp//ccIyuKJc.o
ld: fatal: Symbol referencing errors. No output written to interp
collect2: ld returned 1 exit status*

Can any of you give me some ideas as why this is happening ?

Thanks & Regards,

Viresh
Nick Ing-Simmons
2005-12-15 20:31:58 UTC
Permalink
Post by Viresh Kumar
Hello,
I am facing a problem while running a perl script with arguments within a C
Now the problem comes is regarding the loading of "Digest::MD5" module which
*Can't load module Digest::MD5, dynamic loading not available in this
perl. (You may need to build a new perl executable which either supports
dynamic loading or has the Digest::MD5 module statically linked into it.)
at /opt/perl_5.8.5/lib/sun4-solaris-thread-multi/Devel/Cover/DB/Structure.pm
line 14
Compilation failed in require at
/opt/perl_5.8.5/lib/sun4-solaris-thread-multi/Devel/Cover/DB/Structure.pm
line 14.
BEGIN failed--compilation aborted at
/opt/perl_5.8.5/lib/sun4-solaris-thread-multi/Devel/Cover/DB/Structure.pm
line 14*
#ifdef __cplusplus
# define EXTERN_C extern "C"
#else
# define EXTERN_C extern
#endif
static void xs_init _((void));
EXTERN_C void boot_DynaLoader _((CV* cv));
EXTERN_C void boot_Digest _((CV* cv));
EXTERN_C void
xs_init()
{
char *file = __FILE__;
/* DynaLoader is a special case */
newXS("DynaLoader::boot_DynaLoader", boot_DynaLoader, file);
newXS("Digest::bootstrap", boot_Digest, file);
}
gcc -o interp interp.c `perl -MExtUtils::Embed -e ccopts -e ldopts`
*Undefined first referenced
symbol in file
boot_Digest /var/tmp//ccIyuKJc.o
ld: fatal: Symbol referencing errors. No output written to interp
collect2: ld returned 1 exit status*
Can any of you give me some ideas as why this is happening ?
There is (as far as I know) no Digest.xs so you should NOT add Digest
to xs_init().

Adding just DynaLoader to xs_init should allow your script to dynamically
load Digest::MD5 in the same way perl does.

-----

It is possible statically load it instead but it much more messy.
You would need to build a perl with Digest::MD5 as static so there
is a .a (or .lib) file that defines the symbol.
Or if you built you perl yourself you can find the MD5.o (or .obj)
that got built

and then in C code:

EXTERN_C void boot_Digest__MD5 _((CV* cv));

newXS("Digest::MD5::bootstrap", boot_Digest__MD5, file);

Then you need to find and pass the object/library defining boot_Digest__MD5
to you build process.

Loading...