2009-09-13
perl win32 API编程入门 - [perl]
版权声明:转载时请以超链接形式标明文章原始出处和作者信息及本声明
http://ddle.blogbus.com/logs/46349748.html
让perl实现良好的跨平台性是perlish们一直在努力的事情,如今,随着perl的发展,perl环境的跨平台性已经做得相当稳定,但是,相当多程序还是无法像在UNIX下一样良好、稳定地运行,但是,win32::API模块的出现却多少让我们看到了一些希望。在ActivePerl 5.6的时候,Win32::API默认是不安装的,在到了ActivePerl 5.8的时候,Win32::API已是默认安装的模块,也正是因此这一点,多少引起了笔者的一点注意,所以试探性地使用了一下,很快笔者就发现,模块功能果然如其名,无需调用任何XS外部扩展即可在win32平台下随意调用api函数,使得perl能在win32环境中自由飞翔 ……
废话说得太多了,今天先将入门,简单说几个:
先说一下ActivePerl User Guide里面给出的例子吧,大家用perldoc win32::api看一下pod就可以看到了,例子如下:
use Win32::API;
$obj = Win32::API->new('kernel32.dll','int GetCurrentProcessId()');
$pid = $obj->Call();
print $pid;
注意模块中的大小写问题,用过perl的都知道,熟悉UNIX的朋友更应该不会用错。
程序会返回一个pid值,是程序运行过程的pid值。
这里的程序是ActivePerl User Guide里在描述那节中的第二种形式,之所以先拿这个出来,是因为,对于上面的调用过程,比较符合正常的面向对象的模块编程,所以,这里我认为无需解释什么,很容易懂。
接下来再看同样作用的程序的另一种样子:
use Win32::API;
Win32::API->Import('Kernel32.dll','int GetCurrentProcessId()');
$pid = GetCurrentProcessId();
print $pid;
这里用了个import方法,呵呵,这个作用让我想起了python程序中的import,好怀念,相比之下,因为用惯了python,我更喜欢用这样的方法,我们就可以理解为,import方法将本属于Win32::API这个名字空间中的一个subroutine导入到了当前的名字空间中,成为一个当前程序中全局的subroutine,因此,后面$pid = GetCurrentProcessId();就直接调用了。
解释的是否明白?
呵呵,如果不明白的话看下Programming Perl吧,里面有关于名字空间的解释。
说到这里,一些比较简单的调用方法就已经讲清楚了,呵呵,如果熟悉C或是B程序的读者应该比我还要清楚咯,这里再给一个例子,这个例子的作用是获取windows的错误信息,在给出之前,先写另外一个例子,这个例子是我们没有使用API而只使用perl的win32模块获取win32错误信息的方法:
use Win32;
$err_id = Win32::GetLastError();
print $err_id;
这样返回一个错误的ID值,呵呵,看不懂吧,没关系,win32模块还提供了一个方法用以解释这个ID,如下:
use Win32;
$err_id = Win32::GetLastError();
$err_msg = Win32::FormatMessage($err_id);
print $err_msg;
这里就返回一个信息“系统找不到指定的文件。”,呵呵,看懂了吧(因为程序没调用任何文件,所以返回这样的信息)
好,看完上面的,看一下通过api来获取错误的ID值:
#!/usr/bin/perl
use Win32;
use Win32::API;
$obj = Win32::API->new("Kernel32.dll","int GetLastError()");
$err = $obj->Call();
print "Error Code is : ",$err,"\n";
$err_msg = Win32::FormatMessage($err);
print "Error Msg is : ",$err_msg;
这里讲述了最简单的API调用方法,今天先讲到这里,因为关于API的调用我也正在研究中(呵呵,偶的C语言不好,需要复习一下),到时候如果研究出更强的东西,再和大家分享!