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

2010年12月30日 #

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 @ 2010-12-30 18:14 changup 阅读(2140) | 评论 (0)编辑 收藏

2010年12月24日 #

C、C++程序潜入解释性语言

在做电信宽带认证Radius系统的时候,采用了开源的freeradius系统,其中有个perl的模块非常的方便,多变的业务逻辑交给解释性的perl去执行,这样在后期的维护、上线就边的非常简单,不用修改C程序。近期打算摘一下C和Perl的交互,分离出一个包公用。
请教大家这样的案例还有没有更简单的组合?期待CPP博客的高手们开坛讲经...
补充一下:开源的现成框架更好!

posted @ 2010-12-24 10:22 changup 阅读(2448) | 评论 (5)编辑 收藏

2010年12月23日 #

生成随机数的一段代码

生成随机数的一段代码。引来一片嘘嘘,删掉了一句,呵呵,顶不住了。可是我觉得够用就行了为原则。
改进一下,提高种子的精度,完了引入os的radom设备
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <sys/time.h>

void init_random()
{
 unsigned int ticks;
 struct timeval tv;
 gettimeofday(&tv,NULL);
 ticks = tv.tv_sec + tv.tv_usec;
 srand(ticks);
}

//ibuflen---需要生成的随即串的长度
int genrandstr(char* pszbuf,int ibuflen)
{
    
static const char sourchar[] = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
    init_random();
    
for(int i=0;i<ibuflen;i++)
    {
        
int x = rand()/(RAND_MAX/(sizeof(sourchar)-1));
        pszbuf[i] 
= sourchar[x];
    }
    pszbuf[ibuflen] 
= '\0';
}
int main(int argc, char* argv[])
{
 printf("begin randstr...,RAND_MAX=%d\n",RAND_MAX);
 char buf[9] = {0};
 genrandstr(buf,8);
 printf("randstr=%s\n",buf); 
 genrandstr(buf,8);
 printf("randstr=%s\n",buf);
 genrandstr(buf,8);
 printf("randstr=%s\n",buf);
 genrandstr(buf,8);
 printf("randstr=%s\n",buf);
 genrandstr(buf,8);
 printf("randstr=%s\n",buf);
 genrandstr(buf,8);
 printf("randstr=%s\n",buf);
 printf("end randstr...\n");
    return 0;
}

posted @ 2010-12-23 09:15 changup 阅读(2226) | 评论 (8)编辑 收藏

2010年12月15日 #

继续上一块砖,引来玉。一个命令行参数的解析类CArgNodeList

     摘要:   阅读全文

posted @ 2010-12-15 15:10 changup 阅读(1701) | 评论 (0)编辑 收藏

2010年12月14日 #

单实例模式的一个C++读取配置文件的类CConfig2Map

     摘要: 由于项目中经常遇到读取配置文件的地方,为方便调用虽写了个功能简单,使用方便的配置文件类,基本思路是将配置文件缓冲到map当中,目前只支持一级配置,多级别的树形配置暂不支持,有需要的兄弟请完善。为单实例模式。config2map.h // config2map.h// 配置文件到map的映射类,单实例模式// 创建: 2010-09-13 chan...  阅读全文

posted @ 2010-12-14 15:48 changup 阅读(3662) | 评论 (5)编辑 收藏

一个udp server的仿组件的封装,抛砖引玉

     摘要:   阅读全文

posted @ 2010-12-14 11:34 changup 阅读(2100) | 评论 (1)编辑 收藏

仅列出标题