Perl 对 C 的扩展接口

XS 语言是一种用来在 Perl 和需要在 Perl 内使用的 C 代码(或者 C 库)之间创建扩展的接口描述文件格式。XS 接口为 C 库链接创建了一个静态链接到 Perl 或者能被 Perl 动态导入的新库。本文的主要目的是介绍如何在 Unix 环境下编写 XS 接口并成功通过编译,从而实现 Perl 对 C 的扩展,提高代码重用率。

引言

本文面向 Perl 和 C 的开发人员,旨在通过对 Perl 与 C 之间的 XS 扩展接口的介绍,让读者了解到通过 Perl 调用 C 函数的一种方法。为了更好的理解本文,读者需要具备一定的 Perl 和 C 编程经验,并对 Unix 环境下库文件的编译过程和 Makefile 语法有所了解。







什么是 XS 语言

XS 是一个用来在 Perl 和需要在 Perl 内使用的 C 代码(或者 C 库)之间创建扩展的接口描述文件格式。XS 接口为 C 库链接创建了一个静态链接到 Perl 或者能被 Perl 动态导入的新库。XS 接口描述是用 XS 语言写的,是 Perl 扩展接口的核心部分。

当 Perl 代码调用 C 函数时,XS 从 Perl 堆栈中获取参数,将这些参数转化为 C 函数所要求的正确格式,调用相应的 C 函数,并将返回值转化为 Perl 的参数格式,压入 Perl 堆栈供程序读取,或者直接修改 Perl 所提供的变量值。

由于 Perl 提供了比 C 更为自由的变量定义和调用规则,在参数转换过程中,XS 还必须验证参数合法性,抛出异常(或返回 undef 或空值列表),根据参数的数目和类型的不同调用不同的 C 函数,提供面向对象接口等等。

XS 语言的编译器叫做 xsubpp,它为接口创建必要的数据结构和调用关系,xsubpp 根据 typemaps 来确定如何在 Perl 与 C 之间转换函数参数和返回值。标准 Perl 库自带的 typemap 定义了大部分常用的 C 变量类型,但一些特殊的数据结构和类型需要开发人员通过自定义的 typemap 来实现。







.XS 文件

XSUB 解析

XS 接口文件以 .xs 为后缀名,里面定义了 Perl 与 C 之间的接口函数。XSUB 是 XS 接口的基本结构单元,通过 xsubpp 编译后,每个 XSUB 都为相应的 C 函数提供了 Perl 与 C 之间的调用接口。


清单 1 . 一个简单的 .xs 文件

				  
 #include "EXTERN.h"
 #include "perl.h"
 #include "XSUB.h"
       
 MODULE = TEST   PACKAGE = TEST 
 void 
 hello() 
 CODE: 
 printf("Hello,world!/n"); 


其中前三个 #include 声明:EXTERN.h,perl.h 和 XSUB.h 应该始终出现在每个 XS 文件的开头。其后是其他的头文件 #include 声明。

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

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

一个最简单的 XSUB 由三部分(section)组成:返回值定义;XSUB 函数名和参数名;以及参数类型。复杂的 XSUB 还包括其他部分,如 CODE:(代码段),IUPUT:(输入值),OUTPUT:(输出值)等等。其中返回值和函数名必须位于每个 XSUB 的开头,分行书写并左对齐顶格,其余部分格式则没有严格要求。


清单 2 .XSUB 格式

				  
 double sin(x)        double                 double 
 double x                sin(x)              sin(x) 
                       double x                double x 
  错误                  错误                  正确


Perl 变量堆栈和参数

Perl 变量堆栈(argument stack)用于存放发送给 XSUB 的参数值及其返回值。XSUB 可以通过宏 ST(x) 访问该堆栈,其中 ST(0) 为该堆栈的起始地址。


清单 3 . 操作 ST(x)

				  
 membername = (char*)SvPV(ST(2),na); 
 ST(0) = newSVpv("Hello World",0); 


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


清单 4 . 操作 SP

				  
 EXTEND(SP,2); 


变量 RETVAL 是一个特殊的 C 变量,它的类型对应于 C 函数的返回值类型。xsubpp 编译器会自动为每个 non-void 返回值类型的函数声明该变量,用于存放被调用的 C 函数的返回值。通常情况下,RETVAL 会作为对应 XSUB 的返回值存放到 Perl 变量堆栈的 ST(0)。


清单 5 .RETVAL 变量

				  
 int 
 is_even(input) 
 int input 
 CODE: 
 RETVAL = (input % 2 == 0); 
 OUTPUT: 
 RETVAL 


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

XSUB 的一些关键字

OUTPUT: 关键字指定了当 XSUB 结束时应该返回给调用方 Perl 的参数值。在没有 CODE: 段和 PPCODE: 段时,RETVAL 变量会被自动指定为 OUTPUT 变量,否则需要显式指定 OUTPUT 变量。该关键字也能用于指定函数输入参数为 OUTPUT 变量,这在当函数体改变了某个输入参数值并希望将新值返回给调用方 Perl 的情况下十分有用。


清单 6 .C 函数原型

				  
 bool_t gettime(const char *host,time_t *timep); 


其函数将指定 host 上的当前系统时间存入指针 timp 对应的地址中,同时返回布尔型状态值。


清单 7 . 对应的 XSUB 函数定义

				  
 bool_t 
 gettime(host,timep) 
	 char *host 
	 time_t &timep 
 OUTPUT: 
	 Timep 


CODE: 关键字用于对相应的 C 函数做额外的操作处理,此时 RETVAL 变量仍被声明,但并不作为返回值,除非被 OUTPUT: 关键字显式指定。仍以上面的 C 函数 gettime (host,timep) 为例,如果在 Perl 代码中存在以下的调用:

Perl 代码调用

$status = gettime( "localhost",$timep );

其中 $status 和 $timep 都用于接收 C 函数的返回值,则需要对相应的 C 函数做额外的处理。


清单 9. 对应的 XSUB 函数定义

				  
 bool_t 
 gettime(host,timep) 
	 char *host 
	 time_t timep 
 CODE: 
	 RETVAL = gettime( host,&timep ); 
 OUTPUT: 
	 timep 
	 RETVAL 


通过一元运算符 &,当 xsubpp 编译器调用 C 函数 gettime() 时,传给 C 函数的参数 &timep 是指向 time_t 的指针 time_t *,同时将得到的时间值存储在 timep 中返回给 Perl。

PPCODE: 关键字是对 CODE: 的补充,用于直接操作 Perl 变量堆栈。这在当 XSUB 存在多个返回值时十分有用。此时必须在 PPCODE: 中显式的将返回值列表压入堆栈顶。需要注意的是,在同一个 XSUB 中 CODE: 和 PPCODE: 不能同时出现。

PPCODE: 通常直接操作 SP,通过 PUSH*() 宏将返回值列表压入 Perl 堆栈,而不是将其作为返回值传送给 Perl,因此其函数返回值类型一般为 void,用于告诉 xsubpp 编译器不需要声明和创建 VETVAL 变量。


清单 10.PPCODE: 关键字

				  
 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))); 


通过 PUSH() 宏将 C 函数 gettime() 的返回值 status 和 timep 依次压入 Perl 堆栈,有了上面的 XSUB 定义,则在 Perl 代码中可以这样调用上面的 C 函数 gettime()。

Perl 代码调用

($status,$timep) = gettime("localhost");







编译 XS 文件

编译命令 h2xs

使用 h2xs 来编译并生成 XS 扩展接口所必要的系列文件。h2xs 用于根据 C 头文件 .h 生成相应的 Perl扩展,其扩展模块名字由 -n 参数指定,当没有 -n 参数时,则自动使用第一个 .h 头文件的名字,并将其首字母大写作为扩展模块的名字。


表 1. h2xs 常用参数

参数名 说明
-A --omit-autoload 忽略 autoload 机制
-O --overwrite-ok 允许覆盖已存在的扩展文件
-n --name=module_name 指定扩展模块的名字


更为详细和完整的参数列表可参阅相关文档 perldoc-h2xs。

生成的文件

当执行命令 “h2xs -A -n Mytest” 后,系统在当前目录下创建一个子目录 Mytest,并在其下生成一系列文件:MANIFEST,Makefile.PL,Mytest.pm,Mytest.xs,Mytest.t 和 Changes。

  1. MANIFEST

    MANIFEST 文件包含了在 Mytest 目录下创建的所有文件的名字。



    清单 11 .MANIFEST 文件内容
    				  
     Changes 
     Makefile.PL 
     MANIFEST 
     Mytest.xs 
     ppport.h 
     README 
     Mytest.t 
     lib/Mytest.pm 
     mylib/Makefile.PL 
     mylib/test.c 
     mylib/test.h 
    
  2. Changes

    Changes 文件记录了扩展接口的创建以及后续的修改动作。



    清单 12.Changes 文件内容
    				  
     Revision history for Perl extension Mytest. 
    
     0.01  Tue Jun  2 15:23:11 2009 
     - original version; created by h2xs 1.23 with options 
    	 -A -O -n Mytest ./Mytest/mylib/test.h 
    
  3. Makefile.PL

    Makefile.PL 文件是一个 Perl 脚本,用于自动生成 Makefile,以创建扩展接口。当执行 “Perl Makefile.PL” 命令后,系统生成相应的 Makfile,然后执行 “make” 会在当前目录下生成 blib 子目录,用于存放将要使用到的共享库文件 (shared library)。



    清单 13 . 一个简单的 Makefile.PL
    				  
    use ExtUtils::MakeMaker; 
     # See lib/ExtUtils/MakeMaker.pm for details of how to influence 
     # the contents of the Makefile that is written. 
     WriteMakefile( 
    	 NAME         => 'Mytest',VERSION_FROM => 'Mytest.pm',# finds $VERSION 
    	 LIBS         => [''],# e.g.,'-lm'
    	 DEFINE       => '','-DHAVE_SOMETHING'
    	 INC          => '','-I/usr/include/other'
     ); 
    
  4. Mytest.pm

    Mytest.pm 文件是一个模块文件,定义了 Perl 如何加载该扩展接口。当在 Perl 代码中出现 “use Mytest;” 时,Perl 会在 @INC 数组中定义的目录列表里搜索 Mytest.pm 并加载。然后 Perl 代码就可以直接调用 Mytest.xs 扩展中定义的 C 函数。



    清单 14 .Mytest.pm 框架
    				  
     package Mytest; 
    
     use 5.008008; 
    
     use strict; 
     use warnings; 
    
     require Exporter; 
     our @ISA = qw(Exporter); 
     our %EXPORT_TAGS = ( 'all' => [ qw( 
     )]); 
    
     our $VERSION = '0.01'; 
     require XSLoader; 
     XSLoader::load('Mytest',$VERSION); 
    
     # Preloaded methods go here. 
     1; 	
     __END__ 
     # Below is the stub of documentation for your module. You better edit it! 
    
  5. Mytest.xs

    Mytest.xs 实现了 Perl 扩展接口,通过该接口 Perl 代码可以调用对应 C 文件中定义实现的函数。

  6. Mytest.t

    Mytest.t 文件是代码测试脚本,可以通过执行 “make test” 来测试扩展模块的编译是否正确。



    清单 15 .Mytest.t 框架
    				  
    use Test::More tests => 4; 
     BEGIN { use_ok('Mytest') }; 
    
     # Insert your test code below,the Test::More module is use()ed here so read 
     # its man page ( perldoc Test::More ) for help writing this test script. 
    

编译过程

通常一个 XS 扩展接口的编译过程为以下几步:


清单 16 . 编译步骤

				  
 perl Makefile.PL     
 make                   
 make test 
 make install 


首先运行 ”perl Makefile.PL” 在当前目录生成 Makefile;然后运行 ”make” 编译并创建所需的库文件;之后用 ”make test” 测试编译结果是否正确;最后运行 ”make install” 将库文件安装到系统目录,至此整个编译过程结束。







一个 XS 实例

  1. 在当前目录创建一个子目录 Mytest,在 Mytest 目录下创建子目录 mylib,并将已写好的 C 头文件和源代码放在 mylib 目录下。

    清单 17 . 头文件 test.h
    				  
     #define TESTVAL 	 3 
     extern double 	 add(int,long); 
     extern int    max(int,int); 
    



    清单 18 . 源文件 test1.c
    				  
     #include "./test.h"
     double add(int a,long b) 
     { 
     return (a + b + TESTVAL); 
     } 
    



    清单 19 . 源文件 test2.c
    				  
     #include "./test.h"
     int max(int a,int b) 
     { 
     return ((a>b)? a:b); 
     } 
    
  2. 在 Mytest/mylib 目录下创建 Makefile.PL 文件,以保证在 Mytest 目录运行 ”make” 时会自动调用该 Makefile.PL 并生成相应的 Makefile。

    清单 20 .Mytest/mylib 目录下的 Makefile.PL
    				  
    use ExtUtils::MakeMaker; 
     $Verbose = 1; 
     WriteMakefile( 
     NAME   => 'Mytest::mylib',SKIP   => [qw(all static static_lib dynamic dynamic_lib)],clean  => {'FILES' => 'libmylib$(LIB_EXT)'},); 
    
     sub MY::top_targets { 
    '
     all :: static 
     pure_all :: static 
     static ::  libmylib$(LIB_EXT) 
     libmylib$(LIB_EXT): $(O_FILES) 
     $(AR) cr libmylib$(LIB_EXT) $(O_FILES) 
     $(RANLIB) libmylib$(LIB_EXT) 
    '; 
     } 
    

    在 MY::top_targets 中,通过 ar 将 mylib 子目录下的 test1.o 和 test2.o 编译为静态库 libmylib.a,并通过 ranlib 更新静态库 libmylib.a 的符号索引表。

    注意: $(AR) 和 $(RANLIB) 前面应该是 ‘ Tab ’ 而不是空格,否则 Make 会报 “missing separator” 错误并终止编译。

  3. 在 Mytest 的上级目录中执行命令 “h2xs -A -O -n Mytest ./Mytest/mylib/test.h” 以生成扩展接口系列文件。

    注意:Perl 会提示覆盖 Mytest 目录,并在 Mytest 中生成上节介绍的系列文件,这也是要将源文件放在 /Mytest/mylib/ 下的原因,以免被自动生成的文件覆盖。

  4. Perl 在 Mytest 下自动生成的 Makefile.PL 并不知道子目录 mylib 的存在,因此需要修改该 Makefile.PL。

    清单 21 . 修改 Mytest 目录下的 Makefile.PL
    				  
     WriteMakefile( 
    	 'NAME'         => 'Mytest','VERSION_FROM' => 'Mytest.pm',# finds $VERSION 
    	 'LIBS'         => [''],'-lm'
    	 'DEFINE'       => '','-DHAVE_SOMETHING'
    	 'INC'          => '','-I/usr/include/other'
    	 'MYEXTLIB'     => 'mylib/libmylib$(LIB_EXT)',); 
    

    指定了 MYEXTLIB 为 mylib 子目录下的 libmylib.a。



    清单 22 . 在 Makefile.PL 文件的最后添加 MY::postamble 函数
    				  
     sub MY::postamble { 
    '
     $(MYEXTLIB): mylib/Makefile 
     cd mylib && $(MAKE) $(PASSTHRU) 
    '; 
     } 
    

    在 MY::postamble 中进入 mylib 子目录并运行其下的 Makefile 进行编译,以生成静态库 libmylib.a。

    注意: ‘ cd ’ 前面应该是 ‘ Tab ’ 而不是空格,否则 Make 会报 “missing separator” 错误并终止编译。

  5. 修改 MANIFEST 文件使其能够正确包含该扩展接口的所有内容。

    清单 23 . 修改 MANIFEST 文件
    				  
     mylib/Makefile.PL 
     mylib/test1.c 
     mylib/test2.c 
     mylib/test.h 
    
  6. 修改 Mytest.xs 文件并添加函数定义。

    清单 24 . 修改 #include test.h
    				  
     #include "mylib/test.h"
    

    修改路径为 mylib/test.h 并将尖括号 <> 改为双引号””,以使编译程序能正确找到 mylib 子目录下面的 test.h 头文件。



    清单 25 . 添加 add() 和 max() 函数定义
    				  
     double 
     add(a,b) 
     int  a 
     long b 
    
     int 
     max(a,b) 
       int a 
       int b 
    

    提供 Perl 与 C 之间的接口函数,使得 Perl 代码通过 Mytest.xs 中的接口函数可以直接调用相应的 C 函数 add(a,b) 和 max(a,b) 函数。

  7. 在 Mytest 目录下运行 ”perl Makefile.PL” 生成 Makefile。

    清单 26 . 运行 perl Makefile.PL
    				  
     % perl Makefile.PL 
     Checking if your kit is complete... 
     Looks good 
     Writing Makefile for Mytest::mylib 
     Writing Makefile for Mytest 
     % 
    

    编译器根据 Makefile.PL 自动生成相应的 Makefile 和 mylib 子目录下的 Makefile。

  8. 运行 ”make” 生成需要的库文件。

    清单 27 . 运行 make
    				  
     % make 
     gcc  -c <compile_flag>   test1.c 
     gcc  -c   <compile_flag> test2.c 
     ar cr libmylib.a test1.o test2.o 
     : libmylib.a 
     perl xsubpp -typemap typemap  Mytest.xs > Mytest.xsc && mv Mytest.xsc Mytest.c 
     Please specify prototyping behavior for Mytest.xs (see perlxs manual) 
     gcc  -c  <compile_flag>   Mytest.c 
     rm -f blib/arch/auto/Mytest/Mytest.so 
     gcc <compile_flag> Mytest.o -o blib/arch/auto/Mytest/Mytest.so mylib/libmylib.a 
    
     chmod 755 blib/arch/auto/Mytest/Mytest.so 
     cp Mytest.bs blib/arch/auto/Mytest/Mytest.bs 
     chmod 644 blib/arch/auto/Mytest/Mytest.bs 
     Manifying blib/man3/Mytest.3pm 
     % 
    
  9. 修改 Mytest.t 文件,添加测试代码

    清单 28 . 修改 Mytest.t
    				  
     is( &Mytest::add(1,2),6 ); 
     is( &Mytest::add(3,1),7 ); 
     is( &Mytest::max(1,2 ); 
     is( &Mytest::max(3,3 ); 
    

    测试代码以不同的参数调用 Mytest::add() 和 Mytest::max() 并同预期结果比较,以确认相应的 C 函数 add() 和 max() 被正确调用。

  10. 运行命令 ”make test”,确保所有测试结果正确。

    清单 29 . 运行 make test
    				  
     % make test 
     PERL_DL_NONLAZY=1 /usr/bin/perl "-MExtUtils::Command::MM" "-e" "test_harness 
     (0,'blib/lib','blib/arch')" *.t 
     Mytest....ok                                                               
     All tests successful. 
     Files=1,Tests=4,0 wallclock secs ( 0.03 cusr +  0.01 csys =  0.04 CPU) 
     % 
    

    从结果可以看到测试全部通过,说明相应 C 函数被调用并计算得到了正确的结果。

    1. 运行命令 ”make install”,将生成的库文件安装到系统目录中。
    2. 至此,我们就能在自己的 Perl 代码中直接调用 test1.c 和 test2.c 里面定义的函数 add() 和 max() 了。


    清单 30 .Perl 代码调用
    				  
     use Mytest; 
     my $sum = &Mytest::add(1,2); 
     my $max = &Mytest::max(2,3); 
     print “Sum of 1 add 2 is: $sum/n”; 
     print “Max of 2 and 3 is: $max/n”; 
    







结束语

本文介绍了如何在 Unix 上编写和编译 Perl 对 C 的扩展接口 XS, 使得 Perl 可以调用 C 代码(或者 C 库)中定义的函数。 读者通过本文介绍的详细步骤,可以自行编写 XS 扩展接口,并编译成静态或动态库文件,供 Perl 代码调用。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


1. 如何去重 #!/usr/bin/perl use strict; my %hash; while(&lt;&gt;){ chomp; print &quot;$_n&quot; unless
最近写了一个perl脚本,实现的功能是将表格中其中两列的数据进行拼凑,然后将拼凑后的数据用“|”连接在一起。表格内容如下: 员工号码员工姓名职位入职日期1001张三销售1980/12/17 0:00:
表的数据字典格式如下:如果手动写MySQL建表语句,确认麻烦,还不能保证书写一定正确。写了个Perl脚本,可快速构造MySQL脚本语句。脚本如下:#!/usr/bin/perluse strict;m
巡检类工作经常会出具日报,最近在原有日报的基础上又新增了一个表的数据量统计日报,主要是针对数据库中使用较频繁,数据量又较大的31张表。该日报有两个sheet组成,第一个sheet是数据填写,第二个sh
在实际生产环境中,常常需要从后台日志中截取报文,报文的形式类似于.........一个后台日志有多个报文,每个报文可由操作流水唯一确定。以前用AWK写过一个,程序如下:beginline=`awk &
最近写的一个perl程序,通过关键词匹配统计其出现的频率,让人领略到perl正则表达式的强大,程序如下:#!/usr/bin/perluse strict;my (%hash,%hash1,@arra
忍不住在 PerlChina 邮件列表中盘点了一下 Perl 里的 Web 应用框架(巧的是 PerlBuzz 最近也有一篇相关的讨论帖),于是乎,决定在我自己的 blog 上也贴一下 :) 原生 CGI/FastCGI 的 web app 对于较小的应用非常合适,但稍复杂一些就有些痛苦,但运行效率是最高的 ;) 如果是自己用 Perl 开发高性能的站,多推荐之。 Catalyst, CGI::A
bless有两个参数:对象的引用、类的名称。 类的名称是一个字符串,代表了类的类型信息,这是理解bless的关键。 所谓bless就是把 类型信息 赋予 实例变量。 程序包括5个文件: person.pm :实现了person类 dog.pm :实现了dog类 bless.pl : 正确的使用bless bless.wrong.pl : 错误的使用bless bless.cc : 使用C++语言实
gb2312转Utf的方法: use Encode; my $str = "中文"; $str_cnsoftware = encode("utf-8", decode("gb2312", $str));   Utf转 gb2312的方法: use Encode; my $str = "utf8中文"; $str_cnsoftware = encode("gb2312", decode("utf-8
  perl 计算硬盘利用率, 以%来查看硬盘资源是否存在IO消耗cpu资源情况; 部份代码参考了iostat源码;     #!/usr/bin/perl use Time::HiRes qw(gettimeofday); use POSIX; $SLEEPTIME=3; sub getDiskUtl() { $clock_ticks = POSIX::sysconf( &POSIX::_SC_
1 简单变量 Perl 的 Hello World 是怎么写的呢?请看下面的程序: #!/usr/bin/perl print "Hello World" 这个程序和前面 BASH 的 Hello World 程序几乎相同,只是第一行换成了 #!/usr/bin/perl ,还有显示的时候用的是 print,而不是 echo。有了前面 BASH 基础和 C 语言的基础,许多 Perl 的知识可以很
本文介绍Perl的Perl的简单语法,包括基本输入输出、分支循环控制结构、函数、常用系统调用和文件操作,以及进程管理几部分。 1 基本输入输出 在 BASH 脚本程序中,我们用 read var 来实现从键盘的输入,用 echo $var 来实现输出。那么在 Perl 中将有一点变化。Perl 中将标准输入用关键词 表示;标准输出用 表示,标准错误输出用 表示。故而从标准输入读取数据可以写成: $
正则表达式是 Perl 语言的一大特色,也是 Perl 程序中的一点难点,不过如果大家能够很好的掌握他,就可以轻易地用正则表达式来完成字符串处理的任务,当然在 CGI 程序设计中就更能得心应手了。下面我们列出一些正则表达式书写时的一些基本语法规则。 1 正则表达式的三种形式 首先我们应该知道 Perl 程序中,正则表达式有三种存在形式,他们分别是: 匹配:m/<regexp>/ (还可以简写为 /
在学习Perl和Shell时,有很多人可能会问这样一个问题,到底先学习哪个或者学习哪个更好! 每个人都有自己的想法,以下是个人愚见,请多多指教! Perl是larry wall为解决日常工作中的一个编程问题而产生的,它最初的主要功能是用于分析基于文本的数据和生成这些数据的统计和结果;尽管初衷很简单,但是后来发展了很多特点: 1、Perl是一种借鉴了awk、C、sed、shell、C++、Java等
Perl 有很多命令行参数. 通过它, 我们有机会写出更简单的程序. 在这篇文章里我们来了解一些常用的参数. (重点提示:在window下执行命令行程序的方式为 : perl -e "some code", 注意:是双引号啊,不是单引号,linux下执行时单引号) Safety Net Options 在使用 Perl 尝试一些聪明( 或 stupid) 的想法时, 错误难免会发生. 有经验的 P
转自: http://bbs.chinaunix.net/thread-1191868-1-1.html# 让你的perl代码看起来更像perl代码,而不是像C或者BASIC代码,最好的办法就是去了解perl的内置变量。perl可以通过这些内置变量可以控制程序运行时的诸多方面。 本文中,我们一起领略一下众多内置变量在文件的输入输出控制上的出色表现。 行计数 我决定写这篇文章的一个原因就是,当我发现
2009-02-02 13:07 #!/usr/bin/perl # D.O.M TEAM - 2007 # anonyph; arp; ka0x; xarnuz # 2005 - 2007 # BackConnectShell + Rootlab t00l # priv8! # 3sk0rbut0@gmail.com # # Backconnect by data cha0s (modifica
转自: http://bbs.chinaunix.net/thread-1191868-1-1.html# 让你的perl代码看起来更像perl代码,而不是像C或者BASIC代码,最好的办法就是去了解perl的内置变量。perl可以通过这些内置变量可以控制程序运行时的诸多方面。 本文中,我们一起领略一下众多内置变量在文件的输入输出控制上的出色表现。 行计数 我决定写这篇文章的一个原因就是,当我发现
黑莓 手机 屏幕发展历程对比 blackberry 各型号屏幕大小   黑莓手 机 一直在不断发展且新机型 也在不断上市. 因此,不同黑莓机型的屏幕分辨率也在不断变化着. 总的来说,屏幕分辨率一直在提高并且越来越清晰.我们对所有的黑莓 机型的屏幕分辨率做了个对比.~51blackberry ~com     可能大家特别感兴趣是新发布的黑莓机型,它的分辨率也是黑莓 机型中前所未有的.   黑莓 b
      公司里没有我用惯的UltraEdit的lisence了, 只能无奈转向开源的Notepad++, 找了半天才知道配置运行Perl的办法。         1,用Notepad++打开.pl文件,         2, F5或者Run->Run,打开运行窗口,在下面的框框里输入:Perl -w "$(FULL_CURRENT_PATH)", 然后Save,保存成一个命令就行,名字比如叫R