从另一个具有不同 Active perl 版本的 perl 脚本调用 perl 函数
Call perl function from another perl script with different Active perl versions
我们有两个版本的 Active perl 5.6 和 5.24。我们有必须在 Active perl '5.24' 版本(采用 TLS 1.2 版本)上执行的 Web 服务,这需要从 Active perl '5.6' 版本调用。我们正在使用 windows 操作系统。
遵循的步骤:
在 5.6 版本中执行的调用方代码使用系统 /require 命令调用 5.24 版本。
问题:
如何通过系统命令、要求或等从 5.6 perl 脚本调用 5.24 perl 函数(例如:webservicecall(arg1){return "xyz")?
另外如何获取perl函数5.24的return值?
注:
有两个 perl 版本是暂时的解决方法,我们计划将其升级到更高版本。
"C:\Perl\bin\perl\" 中安装了 perl 5.6 版,"D:\Perl\bin\perl\" 中安装了 perl 5.24 版。
"**p5_6.pl**"
print "Hello Perl5_6\n";
system('D:\Perl\bin\perl D:\sample_program\p5.24.pl');
print $OUTFILE;
$retval = Mul(25, 10);
print ("Return value is $retval\n" );
"**p5_24.pl**"
print "Hello Perl5_24\n";
our $OUTFILE = "Hello test";
sub Mul($$)
{
my($a, $b ) = @_;
my $c = $a * $b;
return($c);
}
我已经为从 perl 脚本 5.6 版本调用 perl 5.24 版本的详细信息编写了示例程序。在执行过程中,我没有得到预期的输出。如何在p5_6.pl脚本中获取"return $c"值和p5_24.pl的"our $OUTFILE"值?
注:以上是示例程序在此基础上我将使用序列化数据修改实际程序
您不能直接调用 Perl 函数 运行 另一个 Perl 版本。您需要创建一个显式调用该函数的程序。输入和输出需要显式序列化以便在这两个程序之间传输。
可以使用 Data::Dumper
、Storable
或类似的方式进行序列化。如果需要较低的性能,您可以调用提供函数的程序 system
并与临时文件或管道共享序列化数据。或者您可以创建一些客户端-服务器架构并与套接字共享序列化数据。后者更快,因为它跳过了另一个进程的重复启动和拆卸,而是保持它 运行.
将需要 v5.24 的函数的代码放在包装器脚本中,这样编写就可以 运行 执行该函数(并打印其结果)。实际上,我建议编写一个具有该功能的模块,然后在包装脚本中加载该模块。
然后 运行 该脚本在所需的 (5.24) 解释器下,通过其完整路径调用它。 (您可能需要小心确保所有库和环境都是正确的。)以允许您获取其输出的方式执行此操作。这可以是任何东西,从反引号 (qx
) 到管道打开,或者更好的是,到好的模块。为此有一系列模块,例如 IPC::System::Simple
、Capture::Tiny
、IPC::Run3
或 IPC::Run
。使用哪个取决于您需要从该呼叫中获得多少。
您不能在 运行ning 程序中调用函数,而是以某种方式在另一个程序中 运行 调用它。
此外,在一个程序中定义的变量(如 $OUTFILE
)在另一个程序中是看不到的。您可以从 v5.24 程序中打印它们以及函数结果,然后在 v5.6 程序中解析整个输出。然后这两个程序将需要一些“协议”——要么遵守打印内容的顺序,要么以某种方式标记打印内容。
更好,编写一个包含需要共享的函数和变量的模块。然后 v5.24 程序可以加载模块并导入它需要的函数和 运行 它,而 v5.6 程序可以加载相同的模块但只能获取该变量(以及 运行 v5.24 程序)。
这是所有这一切的草图。包文件 SharedBetweenPerls.pm
package SharedBetweenPerls;
use warnings;
use strict;
use Exporter qw(import);
our @EXPORT_OK = qw(Mul export_vars);
my $OUTFILE = 'test_filename';
sub Mul { return $_[0] * $_[1] }
sub export_vars { return $OUTFILE }
1;
然后v5.24程序(下面用program_for_5.24.pl
)可以做到
use warnings;
use strict;
# Require this to be run by at least v5.24.0
use v5.24;
# Add path to where the module is, relative to where this script is
# In our demo it's the script's directory ($RealBin)
use FindBin qw($RealBin);
use lib $RealBin;
use SharedBetweenPerls qw(Mul);
my ($v1, $v2) = @ARGV;
print Mul($v1, $v2);
而 v5.6 程序可以做到
use warnings;
use strict;
use feature 'say';
use FindBin qw($RealBin);
use lib $RealBin;
use SharedBetweenPerls qw(export_vars);
my $outfile = export_vars(); #--> 'test_filename'
# Replace "path-to-perl..." with an actual path to a perl
my $from_5.24 = qx(path-to-perl-5.24 program_for_5.24.pl 25 10); #--> 250
say "Got variable: $outfile, and return from function: $from_5.24";
其中 $outfile
有字符串 test_filename
而 $from_5.24
变量是 250
。†
如果两个程序和模块都在同一个目录中,并且名称与本例中的名称相同,则经过测试可以正常工作。 (并将 path-to-perl-5.24
替换为您的 v5.24 可执行文件的实际路径。)如果它们位于不同的位置,您需要调整路径,可能是包名称和 use lib
行。参见 lib pragma。
请注意,有更好的方法来 运行 外部程序 --- 请参阅上面推荐的模块。所有这些都是 粗略的演示 ,因为许多细节取决于您的具体操作。
最后,程序还可以通过套接字连接并交换所需的一切,但这有点复杂,可能不需要。
† 问题已被编辑,现在 path-to-perl-5.24
为 D:\Perl\bin\perl
,program_for_5.24
为 D:\sample_program\p5.24.pl
。
请注意,对于 p5.24.pl
程序的这样一个位置,您必须为模块提供一个合适的位置,然后它的名称需要包含该路径的(一部分)并加载这样的名称。例如参见 [=38=].
没有模块的原始演示(最初发布)
作为一个非常粗略的草图,在您的 运行 低于 v5.6 的程序中,您可以这样做
my $from_5.24 = qx(path-to-perl-5.24 program_for_5.24.pl 25 10);
其中 program_for_5.24.pl
可能类似于
use warnings;
use strict;
sub Mul { return $_[0] * $_[1] }
my ($v1, $v2) = @ARGV;
print Mul($v1, $v2);
并且变量 $from_5.24
在我的测试中最终成为 250
。
我们有两个版本的 Active perl 5.6 和 5.24。我们有必须在 Active perl '5.24' 版本(采用 TLS 1.2 版本)上执行的 Web 服务,这需要从 Active perl '5.6' 版本调用。我们正在使用 windows 操作系统。
遵循的步骤: 在 5.6 版本中执行的调用方代码使用系统 /require 命令调用 5.24 版本。
问题: 如何通过系统命令、要求或等从 5.6 perl 脚本调用 5.24 perl 函数(例如:webservicecall(arg1){return "xyz")? 另外如何获取perl函数5.24的return值?
注: 有两个 perl 版本是暂时的解决方法,我们计划将其升级到更高版本。
"C:\Perl\bin\perl\" 中安装了 perl 5.6 版,"D:\Perl\bin\perl\" 中安装了 perl 5.24 版。
"**p5_6.pl**"
print "Hello Perl5_6\n";
system('D:\Perl\bin\perl D:\sample_program\p5.24.pl');
print $OUTFILE;
$retval = Mul(25, 10);
print ("Return value is $retval\n" );
"**p5_24.pl**"
print "Hello Perl5_24\n";
our $OUTFILE = "Hello test";
sub Mul($$)
{
my($a, $b ) = @_;
my $c = $a * $b;
return($c);
}
我已经为从 perl 脚本 5.6 版本调用 perl 5.24 版本的详细信息编写了示例程序。在执行过程中,我没有得到预期的输出。如何在p5_6.pl脚本中获取"return $c"值和p5_24.pl的"our $OUTFILE"值?
注:以上是示例程序在此基础上我将使用序列化数据修改实际程序
您不能直接调用 Perl 函数 运行 另一个 Perl 版本。您需要创建一个显式调用该函数的程序。输入和输出需要显式序列化以便在这两个程序之间传输。
可以使用 Data::Dumper
、Storable
或类似的方式进行序列化。如果需要较低的性能,您可以调用提供函数的程序 system
并与临时文件或管道共享序列化数据。或者您可以创建一些客户端-服务器架构并与套接字共享序列化数据。后者更快,因为它跳过了另一个进程的重复启动和拆卸,而是保持它 运行.
将需要 v5.24 的函数的代码放在包装器脚本中,这样编写就可以 运行 执行该函数(并打印其结果)。实际上,我建议编写一个具有该功能的模块,然后在包装脚本中加载该模块。
然后 运行 该脚本在所需的 (5.24) 解释器下,通过其完整路径调用它。 (您可能需要小心确保所有库和环境都是正确的。)以允许您获取其输出的方式执行此操作。这可以是任何东西,从反引号 (qx
) 到管道打开,或者更好的是,到好的模块。为此有一系列模块,例如 IPC::System::Simple
、Capture::Tiny
、IPC::Run3
或 IPC::Run
。使用哪个取决于您需要从该呼叫中获得多少。
您不能在 运行ning 程序中调用函数,而是以某种方式在另一个程序中 运行 调用它。
此外,在一个程序中定义的变量(如 $OUTFILE
)在另一个程序中是看不到的。您可以从 v5.24 程序中打印它们以及函数结果,然后在 v5.6 程序中解析整个输出。然后这两个程序将需要一些“协议”——要么遵守打印内容的顺序,要么以某种方式标记打印内容。
更好,编写一个包含需要共享的函数和变量的模块。然后 v5.24 程序可以加载模块并导入它需要的函数和 运行 它,而 v5.6 程序可以加载相同的模块但只能获取该变量(以及 运行 v5.24 程序)。
这是所有这一切的草图。包文件 SharedBetweenPerls.pm
package SharedBetweenPerls;
use warnings;
use strict;
use Exporter qw(import);
our @EXPORT_OK = qw(Mul export_vars);
my $OUTFILE = 'test_filename';
sub Mul { return $_[0] * $_[1] }
sub export_vars { return $OUTFILE }
1;
然后v5.24程序(下面用program_for_5.24.pl
)可以做到
use warnings;
use strict;
# Require this to be run by at least v5.24.0
use v5.24;
# Add path to where the module is, relative to where this script is
# In our demo it's the script's directory ($RealBin)
use FindBin qw($RealBin);
use lib $RealBin;
use SharedBetweenPerls qw(Mul);
my ($v1, $v2) = @ARGV;
print Mul($v1, $v2);
而 v5.6 程序可以做到
use warnings;
use strict;
use feature 'say';
use FindBin qw($RealBin);
use lib $RealBin;
use SharedBetweenPerls qw(export_vars);
my $outfile = export_vars(); #--> 'test_filename'
# Replace "path-to-perl..." with an actual path to a perl
my $from_5.24 = qx(path-to-perl-5.24 program_for_5.24.pl 25 10); #--> 250
say "Got variable: $outfile, and return from function: $from_5.24";
其中 $outfile
有字符串 test_filename
而 $from_5.24
变量是 250
。†
如果两个程序和模块都在同一个目录中,并且名称与本例中的名称相同,则经过测试可以正常工作。 (并将 path-to-perl-5.24
替换为您的 v5.24 可执行文件的实际路径。)如果它们位于不同的位置,您需要调整路径,可能是包名称和 use lib
行。参见 lib pragma。
请注意,有更好的方法来 运行 外部程序 --- 请参阅上面推荐的模块。所有这些都是 粗略的演示 ,因为许多细节取决于您的具体操作。
最后,程序还可以通过套接字连接并交换所需的一切,但这有点复杂,可能不需要。
† 问题已被编辑,现在 path-to-perl-5.24
为 D:\Perl\bin\perl
,program_for_5.24
为 D:\sample_program\p5.24.pl
。
请注意,对于 p5.24.pl
程序的这样一个位置,您必须为模块提供一个合适的位置,然后它的名称需要包含该路径的(一部分)并加载这样的名称。例如参见 [=38=].
没有模块的原始演示(最初发布)
作为一个非常粗略的草图,在您的 运行 低于 v5.6 的程序中,您可以这样做
my $from_5.24 = qx(path-to-perl-5.24 program_for_5.24.pl 25 10);
其中 program_for_5.24.pl
可能类似于
use warnings;
use strict;
sub Mul { return $_[0] * $_[1] }
my ($v1, $v2) = @ARGV;
print Mul($v1, $v2);
并且变量 $from_5.24
在我的测试中最终成为 250
。