2009年12月19日星期六

perlxstut: 用xs创建perl对象

Click here to download:
TObj-0.01.tar.gz (44 KB)

=head1 NAME
 
    使用xs创建perl对象

=head1 AUTHOR

    woosley.xu

=head2  从xs创建类

    void
    new(class)
            char* class
        PREINIT:
            HV* hash;
            SV* obj;
        PPCODE:
            hash = newHV();
            hv_store(hash,"author",6,newSVpv("woosley",0),0);
            obj = newRV_noinc((SV *)hash);
            sv_bless(obj,gv_stashpv("TObj",1));
            XPUSHs(sv_2mortal(obj));

在xs中,创建一个类也和perl中建立类类似,使用相当于bless的sv_bless,其接受的第一个参数是被bless的SV,第二个参数是HV* stash,它可以通过gv_stashpv将一个字符串转化为HV获得。

上面例子中将一个hash bless成名为TObj的类,hash通过newHV创建,并使用hv_store将"author" => "woosley"键值对存入。由于sv_bless需要一个sv,所以将hash通过newRV_noinc转换成为一个RV,在这里noinc意味着不给RV增加引用数,目的是为了防止内存泄漏。

XPUSHs将obj push到perl返回值堆栈,sv_2mortal表明在xs退出后obj会自动清空。

    void
    hello_xs(class)
            HV* class
        PREINIT:
            char* author;
            SV** ve;
        CODE:
            if (ve = hv_fetch(class, "author", 6, FALSE)){
                author = (char *)SvPV_nolen(*ve);
            }
            else {
                Perl_croak(aTHX_"no author found for you");
            }
           
            printf("greet %s: hello from xs\n", author);

这是一个TObj类中的方法,使用$obj->hello_xs传入的第一个参数为$obj,它依然是一个HV,可以从里面使用hv_fetch获得其键值对,使用SvPV_nolen将返回值转化为PV,再强制转化为需要的char*,如果没有author键,则使用Perl_croak打印错误。

=cut

Posted via email from 单行道

没有评论: