只有当我在Windows上运行我的Perl脚本时,如何才能包含Win32模块?

我有一个问题,我似乎无法find答案。

在Perl中,我需要在Windows和Unix平台之间使用脚本。 问题是,在Windows上我们使用Win32-pecific模块,如Win32 :: Process ,而这些模块不存在于Unix上。

我需要一种方法来将这些Win32模块仅包含在Windows上。

if($^O =~ /win/i) { use win32::process qw(CREATE_NEW_CONSOLE); } else { #unix fork } 

问题在于windows的使用声明。 无论我尝试什么,都不会在unix上编译。

我曾尝试过使用dynamicevals,要求BEGIN等。

有没有很好的解决这个问题? 任何帮助将不胜感激。

提前致谢,


更新:

一位同事指出,这是正确的做法。

 require Win32; require Win32::Process; my $flag = Win32::Process::CREATE_NEW_CONSOLE(); Win32::Process::Create($process, $program, $cmd, 0, $flag, ".") || die ErrorReport(); print "Child started, pid = " . getPID() . "\n"; 

感谢大家的帮助!

use在编译时执行。

相反:

 BEGIN { if( $^O eq 'MSWin32' ) { require Win32::Process; # import Win32::Process qw(CREATE_NEW_CONSOLE); Win32::Process->import(qw/ CREATE_NEW_CONSOLE /); } else { #unix fork } } 

见perldoc使用 。

另请参阅$^O上的perlvar 。


更新:

正如Sinan Unur指出的那样,最好避免间接对象​​语法 。

除了调用import之外,我在每种情况下都使用直接方法调用。 可能因为import伪装成内置。 由于import实际上是一个类方法,所以它应该被称为类方法。

谢谢,思南。

另外,在Win32系统上,你需要非常小心,使你的模块名字大写正确。 不正确的大写意味着符号不会被正确导入。 它可以变丑。 use win32::process可能会出现工作正常。

你确定win32 :: process可以在OSX上加载吗? “达尔文”匹配你的/赢/我。
您可能想要使用http://search.cpan.org/dist/Sys-Info-Base/尝试做正确的事情。

除此之外,您可以发布您实际正在使用的代码示例,您收到的失败消息以及哪个unix平台(uname -a)?

怎么样解析器修改每个操作系统上的文件?

你可以通过一个配置脚本来解析你的perl文件,这个脚本可以在两个操作系统上运行,用正确的Use子句输出perl。 您甚至可以将可执行脚本中的分析操作隐藏起来以启动代码。

本来我想从C预编译器指令会做的伎俩,但我不知道perl很好。

以下是对第二组问题的回答:

你使用strictwarnings

你定义了一个ErrorReport()子程序吗? ErrorReport()只是Win32 :: Process的简介中的一个例子。

CREATE_NEW_CONSOLE可能不是数字,因为它没有正确导入。 检查您的呼叫中的大写以import

比较这些单线:

 C:\>perl -Mwin32::process -e "print 'CNC: '. CREATE_NEW_CONSOLE; CNC: CREATE_NEW_CONSOLE C:\>perl -Mwin32::process -Mstrict -e "print 'CNC: '. CREATE_NEW_CONSOLE; Bareword "CREATE_NEW_CONSOLE" not allowed while "strict subs" in use at -e line 1. Execution of -e aborted due to compilation errors. C:\>perl -MWin32::Process -e "print 'CNC: '. CREATE_NEW _CONSOLE; CNC: 16 

您可以将您的特定于平台的代码放在eval{} ,然后检查是否有错误。

 BEGIN{ eval{ require Win32::Process; Win32::Process->import(qw'CREATE_NEW_CONSOLE'); }; if( $@ ){ # $@ is $EVAL_ERROR # Unix code here } }