h2xs -A FloatCalc
然后改写FloatCalc.xs,以下提供3种有别于标准写法的方式。
方式一:
#define PERL_NO_GET_CONTEXT #include "EXTERN.h" #include "perl.h" #include "XSUB.h" #include <stdio.h> XS(XS_FloatCalc_pow) { dXSARGS; if (items != 2) croak("usage:FloatCalc::pow(x,y)"); { double RETVAL; dXSTARG; RETVAL = pow(SvNV(ST(0)),SvNV(ST(1)) ); XSprePUSH; PUSHn(RETVAL); } XSRETURN(1); } XS(boot_FloatCalc) { dXSARGS; const char* file = __FILE__; newXS("FloatCalc::pow",XS_FloatCalc_pow,file); if (PL_unitcheckav) call_list(PL_scopestack_ix,PL_unitcheckav); XSRETURN_YES; }
方式二:
#define PERL_NO_GET_CONTEXT #include "EXTERN.h" #include "perl.h" #include "XSUB.h" #include <stdio.h> XS(XS_FloatCalc_pow) { dXSARGS; if (items != 2) croak("usage:FloatCalc::pow(x,y)"); { double result; sp = mark; result = pow(SvNV(ST(0)),SvNV(ST(1)) ); XPUSHs(sv_2mortal(newSVnv(result))); } XSRETURN(1); } XS(boot_FloatCalc) { dXSARGS; const char* file = __FILE__; newXS("FloatCalc::pow",PL_unitcheckav); XSRETURN_YES; }
方式三:
#define PERL_NO_GET_CONTEXT #include "EXTERN.h" #include "perl.h" #include "XSUB.h" #include <stdio.h> XS(XS_FloatCalc_pow) { dSP; //得到sp dAXMARK; //得到mark dITEMS; //得到items = sp - mark if (items != 2) croak("usage:FloatCalc::pow(x,y)"); { double result; sp = mark; //回到起始位置 result = pow(SvNV(ST(0)),SvNV(ST(1)) ); XPUSHs(sv_2mortal(newSVnv(result))); } PL_stack_sp = sp; //返回栈帧 return; } XS(boot_FloatCalc) { dXSARGS; const char* file = __FILE__; newXS("FloatCalc::pow",PL_unitcheckav); XSRETURN_YES; }
方式四:
#define PERL_NO_GET_CONTEXT #include "EXTERN.h" #include "perl.h" #include "XSUB.h" #include <stdio.h> XS(XS_FloatCalc_pow) { dXSARGS; double result; if (items != 2) { croak("usage:FloatCalc::pow(x,y)"); XSRETURN_EMPTY; } result = pow(SvNV(ST(0)),SvNV(ST(1)) ); XSRETURN_NV(result); } XS(boot_FloatCalc) { I32 ax = POPMARK; //仅需要ax const char* file = __FILE__; newXS("FloatCalc::pow",file); if (PL_unitcheckav) call_list(PL_scopestack_ix,PL_unitcheckav); XSRETURN_YES; }
方式五:
#define PERL_NO_GET_CONTEXT #include "EXTERN.h" #include "perl.h" #include "XSUB.h" #include <stdio.h> XS(XS_FloatCalc_pow) { SV **mark = PL_stack_base + (*PL_markstack_ptr--); int items = PL_stack_sp - mark; double result; if (items != 2) { croak("usage:FloatCalc::pow(x,y)"); PL_stack_sp = mark; return; } result = pow(SvNV(mark[1+0]),SvNV(mark[1+1]) ); mark[1+0] = sv_2mortal(newSVnv(result)); PL_stack_sp = mark +1; return; } XS(boot_FloatCalc) { I32 ax = POPMARK; //仅需要ax const char* file = __FILE__; newXS("FloatCalc::pow",PL_unitcheckav); XSRETURN_YES; }
测试:
#!/usr/bin/perl use FloatCalc; my $result = pow(2.0,4.0); print "pow(2.0,4.0) = $result\n"; my $result = pow(2.0); # 会有用法提示 <>;
结果:
C:\Users\G-Spider\FloatCalc>test.pl pow(2.0,4.0) = 16 usage:FloatCalc::pow(x,y) at C:\Users\G-Spider\Desktop\hello.pl line 6.