如何在64位Perl中解包(64位)unsigned long?

时间:2011-03-30 15:35:01

标签: perl 64-bit unpack

我正在尝试解压缩通过SysV :: IPC从C程序传递到Perl脚本的无符号long值。

众所周知,该值是正确的(我做了一个测试,它将相同的值发送到两个队列,一个由Perl读取,第二个由C应用程序读取),并且所有前导值都被正确读取(使用{{1而不是q来处理64位整数。)

众所周知,PHP中存在something similar错误(在64位计算机上搜索“unsigned long”)(似乎相似: Pack / unpack a 64-bit int on 64-bit architecture in PHP

到目前为止测试的论点:

  • .. Q(=某个值大于预期值)
  • .. L(= 0)
  • ..升! (=大值)
  • .. l(= 0)
  • ..升! (=大值)
  • .. LN! (= 0)
  • .. N,.. N! (= 0)

i! - 没有效果。

详细说明:

  • use bigint; use bignum; = 8;
  • sizeof(unsigned long)一些有意义的空字节......
  • 字节顺序= '12345678';

解决方案:   - Data::Dumper->new([$thatstring])->Useqq(1)->Dump();,填充四个字节。

2 个答案:

答案 0 :(得分:3)

如果您使用64位Perl,则使用the template中的Q解压缩即可使用:

The TEMPLATE is a sequence of characters that give the order
and type of values, as follows:

 ...

 q   A signed quad (64-bit) value.
 Q   An unsigned quad value.
       (Quads are available only if your system supports 64-bit
        integer values _and_ if Perl has been compiled to support those.
        Causes a fatal error otherwise.)

对于更强大的解决方案,将值解压缩为8字节字符串并使用Math::Int64模块将其转换为整数:

use Math::Int64 qw( :native_if_available int64 );

...

$string_value = unpack("A8", $longint_from_the_C_program);

# one of these two functions will work, depending on your system's endian-ness
$int_value = Math::Int64::native_to_int64($string_value);
$int_value = Math::Int64::net_to_int64($string_value);

答案 1 :(得分:1)

解决方案很简单:添加x4Q以跳过实际值之前的四个字节;需要更直观地想到填充/对齐..