Perl+XS(三)

偶使用perl已经有了八、九个年头了,经历过perl的兴衰的历史,虽然如此,perl还是一门非常强大的语言,在perl6即将到来的日子里,希望又能看到一只强壮的骆驼在浩瀚的计算机语言世界里畅行无阻。

三、XS的编写

1XSUB的结构

XS 接口文件以 .xs 为后缀名,里面定义了 Perl C 之间的接口函数。XSUB XS 接口的基本结构单元,通过 xsubpp 编译后,每个 XSUB 都为相应的 C 函数提供了 Perl C 之间的调用接口,如下所示(兼容c++):

#ifdef __cplusplus

extern "C" {

#endif

#include "EXTERN.h"

#include "perl.h"

#include "XSUB.h"

#ifdef __cplusplus

}

#endif

      

MODULE = test   PACKAGE = test PREFIX = t_

void

hello()

CODE:

printf("Hello, world!\n");

其中前三个 #include 声明:EXTERN.hperl.h XSUB.h 应该始终出现在每个 XS 文件的开头。其后是其他的头文件 #include 声明。使用宏__cplusplusextern "C"是为了兼容C++的编译;

MODULE= 定义了该 XS 文件所属的 Perl 模块(.pm),同一个 .xs 文件中所有的 MODULE= 都应该保持一致。每个 MODULE= 之后则是对应的 XSUB 定义,直到文件结束或者下一个 MODULE= 语句;

PACKAGE= 定义了该函数所在的 Package,当同一个 .xs 文件需要被划分为多个 Package PACKAGE= 则需要被显式指定。PACKAGE= 应该和 MODULE= 放在一起并紧随其后;

PREFIX= 定义了下面函数的前缀,只有使用了前缀的函数才能被外部的perl所直接调用;

XSUB中的函数一般由六个部分组成:

I返回值的定义

II函数名和参数名

III参数类型的定义

IV代码段的实现(包括预处理和初始化等等)

v输入值

VI输出值

2Perl的变量堆栈和参数

Perl 变量堆栈(argument stack)用于存放发送给 XSUB 的参数值及其返回值。

1)宏ST

ST(n)

XSUB 可以通过宏 ST(n) 访问该堆栈,其中 ST(0) 为该堆栈的起始地址。

2)宏SP

EXTEND(SP, num);

SP 代表当前 Perl 堆栈指针,当程序从 XSUB 返回时,处理堆栈上的第num个数据。

3RETVAL

变量RETVAL 是一个特殊的C变量,它的类型对应于 C 函数的返回值类型,通常情况下,RETVAL 会作为对应 XSUB 的返回值存放到 Perl 变量堆栈的 ST(0)

XS返回值为void类型时,编译器不会为该函数申明RETVAL变量;而当XSUB存在PPCODE:关键字时,不能对 RETVAL 变量进行操作,而应该直接操作对应的 Perl 变量堆栈 ST(x)

这里关键字CODE:PPCODE:最大的区别是PPCODE直接操作Perl变量堆栈,而不需要将返回值传给Perl

4PUSHs

直接操作Perl变量堆栈的宏

PUSHs(sv_2mortal(newSViv(an_integer)))

PUSHs(sv_2mortal(newSVuv(an_unsigned_integer)))

PUSHs(sv_2mortal(newSVnv(a_double)))

PUSHs(sv_2mortal(newSVpv("Some String",0)))

Perl返回多个值时,可以在PPCODE段使用PUSHs将要返回的值依次压入Perl堆栈:

void

 gettime(host)

      char *host

 PREINIT:

      time_t  timep;

      bool_t  status;

 PPCODE:

      status = gettime( host, &timep );

      EXTEND(SP, 2);

      PUSHs(sv_2mortal(newSViv(status)));

      PUSHs(sv_2mortal(newSViv(timep)));

5XPUSHs

XPUSHs(SV*)

PUSHs,只是不需要再使用EXTEND来扩展这个栈,比如你并不知道这个XSUB返回值的数目,可以使用XPUSHs来自动帮助你完成。

Categories

| | 评论(0)

发表评论

August 2012

      1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31  

关于此日记

此日记由 Cnangel 发表于 September 6, 2009 1:32 PM

此Blog上的上一篇日记Perl+XS(二)

此Blog上的下一篇日记那一片紫色

首页归档页可以看到最新的日记和所有日记。

归档

Powered by Movable Type 5.14-en