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来自动帮助你完成。

Monthly Archives

Pages

Powered by Movable Type 7.7.2

About this Entry

This page contains a single entry by Cnangel published on September 6, 2009 1:32 PM.

Perl+XS(二) was the previous entry in this blog.

那一片紫色 is the next entry in this blog.

Find recent content on the main index or look in the archives to find all content.