在C++上获取对Perl的未定义引用

Getting Undefined Reference to Perl on C++

本文关键字:未定义 引用 Perl C++ 获取      更新时间:2023-10-16

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

我是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

主.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"

没用。。。

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

如果compile选项为cc-o interp interp.c perl -MExtUtils::Embed -e ccopts -e ldopts正如教程所提供的,这是正确的。

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

因此,请确保Makefile-o位于第一位,源文件位于第二位。

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

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