高性能服务器开发;C++深探

c中调用perl的测试小程序,各种场景继续测试中

tar包位置:http://www.cppblog.com/Files/changup/c_perl.tar

本次测试比较完整的一个c文件,贴出来,请高人指点完善,争取大家实际中能用好,毕竟感觉在程序中嵌入解释性的脚本是非常好的,尤其针对复杂多变的业务逻辑部分;

 

#include <stdio.h>
#include 
<string.h>
#include 
<stdlib.h>
#include 
<EXTERN.h>
#include 
<perl.h>

static PerlInterpreter* my_perl;

#define CALLFUN_BEGIN  dSP; \
          ENTER; \
          SAVETMPS; \
          PUSHMARK(SP);
#define CALLFUN_END  FREETMPS;\
          LEAVE;
           


void initperlenv(int argc, char* argv[])
{
    my_perl 
= perl_alloc();
    perl_construct(my_perl);    
    perl_parse(my_perl, NULL, argc, argv, (
char **)NULL);
}

void destroyperlenv()
{
      perl_destruct(my_perl);
      perl_free(my_perl);    
}

/* 普通perl标量的操作
*/
void SV_test()
{
    
//创建
    SV* sv_i = newSViv(99);
    SV
* sv_n = newSVnv(23.45);
    SV
* sv_p = newSVpv("test string",0);
    
    SV
* funstring = 0;
    
    
//将变量设置为mortal;
    sv_2mortal(sv_i);
    sv_2mortal(sv_n);
    sv_2mortal(sv_p);    
    
    
//探测类型
    if(SvIOK(sv_i))
    {
        printf(
"sv_i is a int type,value=%d\n"*(int*)(sv_i->sv_any));
    }
    
else
    {
        printf(
"sv_i is not a int type\n");
    }
    
if(SvNOK(sv_n))
    {
        printf(
"sv_n is a double type\n");
    }
    
else
    {
        printf(
"sv_n is not a double type\n");
    }
    
if(SvPOK(sv_p))
    {
        printf(
"sv_p is a string type\n");
    }
    
else
    {
        printf(
"sv_p is not a string type\n");
    }
    
    
//探测类型,这次打印出的是类型的宏定义
    printf("sv_i.type=%u\n", SvTYPE(sv_i));
    printf(
"sv_n.type=%u\n", SvTYPE(sv_n));
    printf(
"sv_p.type=%u\n", SvTYPE(sv_p));
    
    
//以优美的格式打印标量
    sv_dump(sv_i);
    sv_dump(sv_n);
    sv_dump(sv_p);
    
    
//修改值
    sv_setiv(sv_i,89);
    sv_dump(sv_i);
    sv_setnv(sv_n,
89.76);
    sv_dump(sv_n);
    sv_setpv(sv_p,
"String changed");
    sv_dump(sv_p);
    
    
//操作pl脚本中的文件
    funstring = perl_get_sv("main::getstring",1); //没有得到值
    sv_dump(funstring);
}

/* 操作perl函数
sub fun1()
{
    $username = shift;
    $arg = shift;
    print "your name=$username,your arg=$arg\n";
    return 88;
}
*/
int call_fun()
{
    
//调用函数前的perl堆栈操作
    CALLFUN_BEGIN;
    
    
//参数入栈
    XPUSHs(sv_2mortal(newSVpv("changym",0)));
    XPUSHs(sv_2mortal(newSViv(
32)));
    PUTBACK; 
//表示参数完了
    
    
//调用函数
    perl_call_pv("fun1",G_SCALAR); //G_SCALAR---返回标量;G_ARRAY--返回数组
    /*
    #define G_SCALAR        0
    #define G_ARRAY         1
    #define G_VOID          128     /* skip this bit when adding flags below 
*/
    
    
//extra flags for Perl_call_* routines
    
//#define G_DISCARD       2       /* Call FREETMPS. */
    
//#define G_EVAL          4       /* Assume eval {} around subroutine call. */
    
//#define G_NOARGS        8       /* Don't construct a @_ array. */
    
//#define G_KEEPERR      16       /* Append errors to $@, don't overwrite it */
    
//#define G_NODEBUG      32       /* Disable debugging at toplevel.  */
    
//#define G_METHOD       64       /* Calling method. */
    
    
//开始操作返回值了
    SPAGAIN;
    printf(
"inner ibm.pl,fun1 return %s\n",POPp); //POPi---int, POPp--pchar
    PUTBACK; //表示返回值取完了
    
    
//perl栈资源回收
    CALLFUN_END;
    
return 0;
}

/* 操作perl函数,perl 函数返回一个数组
sub return_array()
{
    @arr = ("changym","chenjx","changjr","xiaobaobao");
    print "inner ibm.pl.return_array:@arr\n";
}
*/
int call_fun_ret_array()
{
    
int ireturn = 0;
    STRLEN n_a; 
//诡异的现象,非要定义这个否则打印值的哪行就报错
                
//ibm.c:162: `n_a' undeclared (first use in this function)
                
//同样的问题就是PerlInterpreter的名字必须叫my_perl,为什么啊?
    
//调用函数前的perl堆栈操作
    CALLFUN_BEGIN;    
    PUTBACK; 
//表示参数完了
    
    
//调用函数
    ireturn = perl_call_pv("return_array",G_ARRAY); //G_SCALAR---返回标量;G_ARRAY--返回数组
    
//开始操作返回值了
    SPAGAIN;
    
if(ireturn>0)
    {
        
while(ireturn>0)
        {
            
//返回的顺序是数组的倒叙啊?
            printf("coming from ibm.pl.return_array:%d-%s\n",ireturn--,POPpx);
        }
    }
    
    PUTBACK; 
//表示返回值取完了    
    
//perl栈资源回收
    CALLFUN_END;
    
return 0;
}


int main(int argc, char* argv[])
{
    
char* my_argv[] = {"","ibm.pl"};
    printf(
"begin c_perl_ibm_test\n");
    printf(
"init perl env\n");
    
    initperlenv(
2,my_argv);
    
    
//标量操作测试
    
//SV_test();
    
    
//函数操作测试
    
//call_fun();
    
    
//操作perl函数返回数组测试
    call_fun_ret_array();    
    
    destroyperlenv();    
    printf(
"leaved c_perl_ibm_test\n");
    
return 0;
}

 

posted on 2010-12-30 18:14 changup 阅读(2163) 评论(0)  编辑 收藏 引用 所属分类: 设计模式实践随想


只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   博问   Chat2DB   管理