3 votes

Obtenir une référence indéfinie à Perl sur C++

Eh bien, tout d'abord, désolé pour mon mauvais anglais !

Je suis nouveau sur linux, g++ et perl, et j'ai quelques problèmes ici.

J'ai un code en G++ qui appelle un fichier perl .pl pour retourner une information. Pour l'instant, je ne renvoie que 1 ou 0 à partir du fichier perl .pl pour des tests et pour comprendre comment cela fonctionne. Mais le problème est que j'obtiens ceci du $make :

sathlervbn Spam C # make clean;make
rm -f *.o
g++  -Wall  -D_REENTRANT -D_GNU_SOURCE -DDEBIAN -fstack-protector -fno-strict-aliasing -pipe -I/usr/local/include -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64  -I/usr/lib/perl/5.14/CORE   -c -o filedir.o filedir.cpp
g++  -Wall  -D_REENTRANT -D_GNU_SOURCE -DDEBIAN -fstack-protector -fno-strict-aliasing -pipe -I/usr/local/include -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64  -I/usr/lib/perl/5.14/CORE   -c -o main.o main.cpp
main.cpp: In function ‘int main(int, char**, char**)’:
main.cpp:112:41: warning: deprecated conversion from string constant to ‘char*’ [-Wwrite-strings]
main.cpp:112:41: warning: deprecated conversion from string constant to ‘char*’ [-Wwrite-strings]
g++ -L/usr/lib -Wall -Wl,-E  -fstack-protector -L/usr/local/lib  -L/usr/lib/perl/5.14/CORE -    lperl -ldl -lm -lpthread -lc -lcrypt -o main filedir.o main.o
main.o: In function `getInfoPerl(std::string)':
main.cpp:(.text+0x1a): undefined reference to `Perl_push_scope'
main.cpp:(.text+0x33): undefined reference to `Perl_save_int'
main.cpp:(.text+0x73): undefined reference to `Perl_markstack_grow'
main.cpp:(.text+0xcd): undefined reference to `Perl_stack_grow'
main.cpp:(.text+0xfa): undefined reference to `Perl_newSVpv'
main.cpp:(.text+0x10d): undefined reference to `Perl_sv_2mortal'
main.cpp:(.text+0x13b): undefined reference to `Perl_call_pv'
main.cpp:(.text+0x18f): undefined reference to `Perl_sv_2iv_flags'
main.cpp:(.text+0x1bd): undefined reference to `Perl_free_tmps'
main.cpp:(.text+0x1ca): undefined reference to `Perl_pop_scope'
main.o: In function `main':
main.cpp:(.text+0x206): undefined reference to `Perl_sys_init3'
main.cpp:(.text+0x20b): undefined reference to `perl_alloc'
main.cpp:(.text+0x21d): undefined reference to `perl_construct'
main.cpp:(.text+0x265): undefined reference to `perl_parse'
main.cpp:(.text+0x272): undefined reference to `perl_run'
main.cpp:(.text+0x2fd): undefined reference to `perl_destruct'
main.cpp:(.text+0x30a): undefined reference to `perl_free'
main.cpp:(.text+0x30f): undefined reference to `Perl_sys_term'
collect2: error: ld returned 1 exit status
make: *** [main] Error 1

Le code du fichier main.cpp est :

#include <EXTERN.h>
#include <perl.h>
#include <iostream>
#include <cstdio>
#include "filedir.h"

using namespace std;  

PerlInterpreter *my_perl;

int getInfoPerl(string email){
    dSP;
    ENTER;
    SAVETMPS;
    PUSHMARK(SP);
    XPUSHs(sv_2mortal(newSVpv(email.c_str(),0)));
    PUTBACK;
    call_pv("spamTeste", G_SCALAR);
    SPAGAIN;

    int resultado = POPi;
    PUTBACK;
    FREETMPS;
    LEAVE;

    return resultado;

}

    int main(int argc, char **argv, char **env) {

    char *my_argv[] = { " ", "spamPerl.pl" };
    PERL_SYS_INIT3 (&argc, &argv, &env);

    my_perl = perl_alloc();
    perl_construct ( my_perl );
    PL_exit_flags |= PERL_EXIT_DESTRUCT_END;

    perl_parse(my_perl, NULL, 2, my_argv, (char **)NULL);
    perl_run(my_perl);

    cout << "Resultado " << getInfoPerl("email/email.txt") << endl;

    perl_destruct(my_perl);
    perl_free(my_perl);

    PERL_SYS_TERM();

    foobar bla bla bla another part from the code: doesn't matter.
}

Voici le makefile :

#CC= /usr/bin/g++
CPP = g++
CPPFLAGS = -Wall $(shell perl -MExtUtils::Embed -e ccopts)
#LD= /usr/bin/g++
LD = g++

LFLAGS = -Wall $(shell perl -MExtUtils::Embed -e ldopts)

#LFLAGS = -Wall -Wl,-E  -fstack-protector -L/usr/local/lib  -L/usr/lib/perl/5.14/CORE -lperl     -ldl -lm -lpthread -lc -lcrypt

MAINOBJS = filedir.o main.o

EMAILS = main

EXECS = $(EMAILS)

#Regra Implicita:
.c.o:
    $(CPP) $(CPPFLAGS) -c $<

all: emails

emails: $(EMAILS)

main: $(MAINOBJS)
    $(LD) -L/usr/lib $(LFLAGS) -o $@ $(MAINOBJS)

clean:
    rm -f *.o

Ce que j'ai fait ? J'ai essayé d'installer le paquet libperl-dev, de mettre à jour le perl, et rien n'a été résolu. J'ai vraiment besoin de résoudre ce problème ! Quelqu'un peut-il m'aider ?

UPDATE :

J'ai changé l'en-tête de main.cpp en :

#ifdef __cplusplus
extern "C" {
#endif
#include "EXTERN.h"
#include "perl.h"
#ifdef __cplusplus
}
#endif

#include <iostream>
#include <cstdio>
#include "filedir.h"

Ça n'a pas marché...

3voto

SetupX Points 109

La réponse précédente est juste, cela est dû à la séquence des paramètres de gcc. Je teste un exemple de code fourni par le tutoriel officiel de perlembed : http://perldoc.perl.org/perlembed.html

si l'option de compilation est cc -o interp interp.c perl -MExtUtils::Embed -e ccopts -e ldopts tel que fourni par le tutoriel, c'est juste.

Mais toute autre séquence est fausse, par exemple : cc interp.c -o interp perl -MExtUtils::Embed -e ccopts -e ldopts cc perl -MExtUtils::Embed -e ccopts -e ldopts interp.c -o interp

donc assurez-vous que dans votre Makefile -o soit le premier et que le fichier source soit le second.

1voto

PhaSath Points 156

Le problème était dans le makefile :

#CC= /usr/bin/g++
CPP = g++
CPPFLAGS = -Wall $(shell perl -MExtUtils::Embed -e ccopts)
#LD= /usr/bin/g++
LD = g++

LFLAGS = -Wall $(shell perl -MExtUtils::Embed -e ldopts)

#LFLAGS = -Wall -Wl,-E  -fstack-protector -L/usr/local/lib  -L/usr/lib/perl/5.14/CORE -lperl     -ldl -lm -lpthread -lc -lcrypt

MAINOBJS = filedir.o main.o

EMAILS = main

EXECS = $(EMAILS)

#Regra Implicita:
.c.o:
$(CPP) $(CPPFLAGS) -c $<

all: emails

emails: $(EMAILS)

main: $(MAINOBJS)
    $(LD) -L/usr/lib $(LFLAGS) -o $@ $(MAINOBJS)

clean:
    rm -f *.o

Comme vous pouvez le voir, dans cette ligne, le code :

main: $(MAINOBJS)
    $(LD) -L/usr/lib $(LFLAGS) -o $@ $(MAINOBJS)

Il devrait y avoir le $(LFLAGS) après le $(MAINOBJS), donc ça devrait être :

main: $(MAINOBJS)
    $(LD) -L/usr/lib -o $@ $(MAINOBJS) $(LFLAGS)

Maintenant, le linker fonctionne parfaitement. Je suis désolé, mais je ne peux pas dire exactement pourquoi cela est nécessaire, je viens de le découvrir.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X