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", 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)
{
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", 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;
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", 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)
{
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", XS_FloatCalc_pow, file);
if (PL_unitcheckav)
call_list(PL_scopestack_ix, 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.