无法向Perl中的Win32::API调用传递压缩句柄数组
我正在尝试使用Win32::API从Perl调用Win32 API函数,并将句柄数组传递给它。特定的函数是无法向Perl中的Win32::API调用传递压缩句柄数组,perl,winapi,pack,Perl,Winapi,Pack,我正在尝试使用Win32::API从Perl调用Win32 API函数,并将句柄数组传递给它。特定的函数是WaitForMultipleObjects,它不喜欢我向它提供参数的方式。以下是它在Perl中的定义: # DWORD WaitForMultipleObjects(DWORD nCount, HANDLE* handles, BOOL, DWORD) $WaitForMultipleObjects = new Win32::API::More('kernel32',
WaitForMultipleObjects
,它不喜欢我向它提供参数的方式。以下是它在Perl中的定义:
# DWORD WaitForMultipleObjects(DWORD nCount, HANDLE* handles, BOOL, DWORD)
$WaitForMultipleObjects = new Win32::API::More('kernel32',
'WaitForMultipleObjects', 'NPNN', 'N');
然后是句柄数组。所有这些都已确认有效,并且在分别传递到WaitForSingleObject
时,它们都有效。
以下是我如何打包参数:
my @handles;
...
my $n = scalar(@handles);
my $handlePack = pack "L*", @handles; # also tried 'L1', 'L2', etc.
$rc = $WaitForMultipleObjects->Call($n, $handlePack, 0, 0xffffffff); # fails
此操作失败,GetLastError()报告错误6(句柄无效)。
但是,如果我只传递一个句柄,它将起作用:
my $handlePack = pack "L", $handles[0];
$rc = $WaitForMultipleObjects->Call(1, $handlePack, 0, 0xffffffff); # works
显然,Win32::API无法在第二个参数中正确传递句柄数组,但就我对文档()的理解而言,应该是这样的。还是我使用的
pack()
有误?如果需要的话,我使用的是64位Perl 问题是64位。在64位Windows(以及64位Perl)上,sizeof(HANDLE)=8个字节。因此,如果程序在64位Perl中运行,它将加载64位DLL,并且必须使用Q
(即64位整数)打包句柄。使用L
将不起作用,因为它包含32位整数。以下内容修复了该问题:
use Config qw( %Config );
my $ptr_size = $Config{ptrsize};
my $ptr_format =
$ptr_size == 4 ? "L" :
$ptr_size == 8 ? "Q" :
die("Unsupported pointer size $ptr_size\n");
my $handlePack = pack $ptr_format."*", @handles;
$rc = $WaitForMultipleObjects->Call($n, $handlePack, 0, 0xffffffff);
请注意,即使在64位Perl中,pack('I')
仍然可以生成32位(取决于编译器)pack('J')
(Perl的内部int)也不合适,因为它至少与指针一样大,但也可能更大(例如,使用-duse64bit
构建的32位Perl)