I'm working on a project embedding and extending perl into a CAD API.
The API allows for an external executable that communicates through
an RPC mechanism, or a shared library loaded dynamically. The choice
is made at link time by the selection of the appropriate library.
I've had great success on Solaris8/gcc with the external executable
using a statically built perl and everything runs as expected. The
shared library method using the same perl has caused some problems
when using C based perl modules.
When using this 'go.pl':
use Data::Dumper;
print "hello world", "\n";
I get the following error message:
Can't load '/usr/perl/lib/5.6.1/sun4-solaris/auto/Data/Dumper/Dumper.so'
for module Data::Dumper: ld.so.1: /opt/pro/sun4_solaris/obj/pro: fatal:
relocation error: file
/usr/perl/lib/5.6.1/sun4-solaris/auto/Data/Dumper/Dumper.so:
symbol main: referenced symbol not found at
/usr/perl/lib/5.6.1/sun4-solaris/XSLoader.pm line 75.
at /usr/perl/lib/5.6.1/sun4-solaris/Data/Dumper.pm line 27
Compilation failed in require at go.pl line 5.
BEGIN failed--compilation aborted at go.pl line 5.
With just the print statement, the script runs just fine. Can someone
give me some suggestions on resolving this problem?
Thanks,
Marc
-----------------------------------------------------------------------
My embedded perl looks like this, which contains code mostly from
perlmain.c, but also from 'perl -MO=C' out of desperation. The
entry point is user_initialize(), which is called by the API:
#include "EXTERN.h"
#include "perl.h"
#include "XSUB.h"
#include "ProToolkit.h"
#include "ProMessage.h"
EXTERN_C void boot_DynaLoader (pTHX_ CV* cv);
static void xs_init (pTHX);
static void dl_init (pTHX);
static PerlInterpreter *my_perl;
int user_initialize(int argc, char **argv) {
int exitstatus;
char *argv1[] = { "", "go.pl" };
char **env_new=NULL, *args[] = { NULL };
int i,argc1=2;
#ifdef PERL_GLOBAL_STRUCT
#define PERLVAR(var,type) /**/
#define PERLVARA(var,type) /**/
#define PERLVARI(var,type,init) PL_Vars.var = init;
#define PERLVARIC(var,type,init) PL_Vars.var = init;
#include "perlvars.h"
#undef PERLVAR
#undef PERLVARA
#undef PERLVARI
#undef PERLVARIC
#endif
printf("Start user_initialize\n");
/* PERL_SYS_INIT3(&argc,&argv,&env); */
PERL_SYS_INIT3(&argc1,&argv1,&env_new);
if (!PL_do_undump) {
my_perl = perl_alloc();
if (!my_perl)
exit(1);
perl_construct(my_perl);
PL_perl_destruct_level = 0;
}
/* exitstatus = perl_parse(my_perl, xs_init, argc, argv, (char **)NULL); */
exitstatus = perl_parse(my_perl, xs_init, argc1, argv1, (char **)NULL);
if (!exitstatus) {
dl_init(aTHX);
exitstatus = perl_run(my_perl);
}
printf("End user_initialize\n");
return(0);
}
void user_terminate() {
printf("Start: User Terminate\n");
perl_destruct(my_perl);
perl_free(my_perl);
PERL_SYS_TERM();
printf("End: User Terminate\n");
}
static void
xs_init(pTHX)
{
char *file = __FILE__;
dXSUB_SYS;
{
/* DynaLoader is a special case */
newXS("DynaLoader::boot_DynaLoader", boot_DynaLoader, file);
}
}
static void
dl_init(pTHX)
{
char *file = __FILE__;
dTARG;
dSP;
/* Dynamicboot strapping code*/
SAVETMPS;
targ=sv_newmortal();
FREETMPS;
/* end Dynamic bootstrapping code */
}
-----------------------------------------------------------------------
My Makefile contains this:
# Executable names
EXE = properl
EXE_DLL = properl.dll
# Include File Paths
INCS = -I. -Iincludes
PERL_INCS=-D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64
-I/usr/perl/lib/5.6.1/sun4-solaris/CORE
# Compiler Flags
CC = gcc
MACH = -DPRO_MACHINE=19 -DPRO_OS=3 -DSOLARIS
CCFLAGS = -c -fPIC
CFLAGS = $(CCFLAGS) $(MACH) $(INCS) $(PERL_INCS)
# Link Flags
LD = ld
LDFLAGS = -G -Bsymbolic
# Libraries
SYSLIBS = -lsocket -lnsl -lw -lm -ldl -lc
PTCLIBS = ./protoolkit.a
PTCLIBS_DLL = ./protk_dll.a
PERL_LIBS = /usr/perl/lib/5.6.1/sun4-solaris/auto/DynaLoader/DynaLoader.a \
-L/usr/perl/lib/5.6.1/sun4-solaris/CORE -lperl \
-L/opt/gcc-2.95.3/lib/gcc-lib/sparc-sun-solaris2.6/2.95.3 -lgcc \
# Object files
OBJS = properl.o
$(EXE): $(OBJS) $(PTCLIBS)
$(CC) -o $(EXE) $(OBJS) $(PTCLIBS) $(SYSLIBS) $(PERL_LIBS)
$(EXE_DLL): $(OBJS) $(PTCLIBS_DLL)
$(LD) $(LDFLAGS) -o $(EXE_DLL) $(OBJS) $(PTCLIBS_DLL) $(PERL_LIBS)
$(SYSLIBS)
# object dependencies
properl.o: properl.c
$(CC) $(CFLAGS) properl.c
dll: $(EXE_DLL)
Marc
--
Marc Mettes
CAD Support
Bic Corporation