3

好吧,首先,对不起我的英语不好!

我是 linux、g++ 和 perl 的新手,我在这里遇到了一些问题。

我在 G++ 中有一个代码,它调用 perl .pl 文件来返回信息。现在,我只是从 perl .pl 文件中返回 1 或 0 以进行测试并了解它是如何工作的。但问题是我从 $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

main.cpp 代码为:

#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.
}

这是生成文件:

#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

我做了什么?我试过安装 libperl-dev 包,更新 perl,但没有解决。我真的需要解决这个问题!有人能帮我吗?

更新:

将标头从 main.cpp 更改为:

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

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

没用...

4

2 回答 2

3

前面的答案是对的,是gcc参数顺序造成的。我测试了官方 perlembed 教程提供的示例代码:http: //perldoc.perl.org/perlembed.html

如果编译选项是教程提供的 cc -o interp interp.c perl -MExtUtils::Embed -e ccopts -e ldopts ,那就对了。

但是任何其他顺序都是错误的,例如: cc interp.c -o interp perl -MExtUtils::Embed -e ccopts -e ldopts cc perl -MExtUtils::Embed -e ccopts -e ldoptsinterp.c -o interp

所以请确保在您的 Makefile -o 中排在第一个,源文件排在第二个。

于 2014-02-07T03:14:39.840 回答
1

问题出在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

如您所见,在这一行中,代码:

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

在 $(MAINOBJS) 之后应该有 $(LFLAGS),所以它应该是:

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

现在,链接器工作正常。对不起,但我不能确切地说为什么这是必要的,我刚刚发现。

于 2013-07-12T23:19:47.537 回答