C++ 调用 perl 代码 - eval_sv 不将参数传递给脚本

标签 c++ perl xs

我有下面的示例程序,它将参数推送到 Perl 堆栈,然后调用“eval_sv”。执行了示例 perl 语句,但我无法检索作为 Perl 参数从 C++ 传递的变量。请让我知道我在下面的程序中缺少什么

程序的输出

Hello World

Test

100Testing complete

这一行不打印 $a 和 $b 的值

string three = "print 'Test\n'; my $z = 100; print $a; print $b; print $z;";

这是我的代码:

#include <EXTERN.h>
#include <perl.h>
#include <string>
using namespace std;
  
string perlScript;

static PerlInterpreter *my_perl;

SV* my_eval_sv(I32 croak_on_error)
{
    STRLEN n_a;
    char *p1 = new char [perlScript.size()+1];
    strcpy(p1, perlScript.c_str());
    const char *p = p1;
    int len = strlen(p);

    dSP;
    ENTER ;
    SAVETMPS ;
    PUSHMARK(SP) ;


    int a, b;
    a = 10;
    b = 20;

    PERL_SET_CONTEXT(my_perl);
    XPUSHs(sv_2mortal(newSViv(a)));
    PERL_SET_CONTEXT(my_perl);
    XPUSHs(sv_2mortal(newSViv(b)));


    /* Done with pushing pointers to Perl stack */

    PUTBACK;

    SV* sv1 = newSVpv(p, 0);    
    eval_sv(sv1, G_EVAL | G_KEEPERR);
    SvREFCNT_dec(sv1);

    SPAGAIN;
    sv1 = POPs;
    PUTBACK;

    FREETMPS;
    LEAVE;

    if (croak_on_error && SvTRUE(ERRSV))
        croak(SvPVx(ERRSV, n_a));   
}

main (int argc, char **argv, char **env)
{
    char *embedding[] = { "", "-e", "0" };
    PERL_SYS_INIT3(&argc,&argv,&env);
    my_perl = perl_alloc();
    perl_construct(my_perl);
    perl_parse(my_perl, NULL, 3, embedding, NULL);
    PL_exit_flags |= PERL_EXIT_DESTRUCT_END;
   
    /*string perlBeginScript;
    static const char * perlEndScript = "\
                                 \n\
    }\n\
    ";

    if(perlBeginScript.length()==0)
    {
        perlBeginScript="EmbeddedPerl";
    }

    perlScript = "sub ";
    perlScript += perlBeginScript;
    perlScript += "{\n"; */

    string one = "print 'Hello World\n'; ";
    string two = "my $a = shift; my $b = shift; ";
    string three= "print 'Test\n'; my $z = 100; print $a; print $b; print $z;";
    string four = "print 'Testing complete\n';";

    perlScript += one ;
    perlScript += two;
    perlScript += three;
    perlScript += four;

    //perlScript += perlEndScript;

    /* Done with perl script to be executed */
    my_eval_sv(TRUE);
    PL_perl_destruct_level = 1;
    perl_destruct(my_perl);
    perl_free(my_perl);
    PERL_SYS_TERM(); 
    }

最佳答案

我只是猜测...

您尝试通过将一些值放在 Perl 堆栈中来将它们传递给您的 Perl 代码,然后您期望 shift 调用从堆栈中检索值。

根据作用域,shift 使用@_@ARGV,两者都不能与“堆栈”互换。仅通过调用 perl 子例程 @_ 来填充堆栈中的元素。这是通过 perlcall 中描述的 call_sv 函数完成的。手册页。

在您的情况下,shift 不是从子例程内部调用的,因此它会尝试从 @ARGV 转移。但由于此数组为空,您的变量将被设置为 undef,这与您获得的输出一致。

如果您需要传递参数,我建议您将 Perl 代码编写为匿名子路由。那就是用 eval_pv() 评估你的子程序定义,然后在设置堆栈后用 call_sv() 调用它。您代码中被注释掉的部分似乎表明您已经研究过这种方法(但使用了命名的子例程)。

或者,您需要通过使用 get_av 退出它来将您的参数推送到 @ARGV,然后对其执行适当的操作。虽然我不确定 @ARGV 是否有任何魔力。

关于C++ 调用 perl 代码 - eval_sv 不将参数传递给脚本,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12403729/

相关文章:

c++ - BST 代码不适用于大数字

perl - 如何将字符串参数的长度传递给 XS 中的 CODE 部分?

c++ - 优雅的模板特化

c++ - 面试测试中使用的LinkedList

perl - 使用基于 WSDL 的 SOAP::Lite

regex - 使用 MARPA::R2 perl 解析双引号字符串

linux - 如何在 Linux 的 Perl 中使用带有 fcgi 的 unix 域套接字的抽象名称?

perl - 如何有条件地将 C 代码片段编译到我的 Perl 模块?

perl - 为什么 XS 潜艇使用 const char *?

c++ - cc1plus : error: unrecognized command line option "-stdlib=libstdc++" with hxcpp