How to unpack (64-bit) unsigned long in 64-bit Perl?

前提是你 提交于 2019-12-07 15:22:18

问题


I'm trying to unpack an unsigned long value that is passed from a C program to a Perl script via SysV::IPC.

It is known that the value is correct (I made a test which sends the same value into two queues, one read by Perl and the second by the C application), and all predecessing values are read correctly (used q instead of i! to work with 64-bit integers).

It is also known that PHP had something similar in bugs (search for "unsigned long on 64 bit machines") (seems to be similar: Pack / unpack a 64-bit int on 64-bit architecture in PHP)

Arguments tested so far:

  • ..Q ( = some value that is larger than expected)
  • ..L ( = 0)
  • ..L! ( = large value)
  • ..l ( = 0)
  • ..l! ( = large value)
  • ..lN! ( = 0)
  • ..N, ..N! ( = 0)

use bigint; use bignum; -- no effect.

Details:

  • sizeof(unsigned long) = 8;
  • Data::Dumper->new([$thatstring])->Useqq(1)->Dump(); a lot of null bytes along some meaningful..
  • byteorder='12345678';

Solution: - x4Q with padding four bytes.


回答1:


Unpacking using Q in the template works out of the box if you have 64-bit Perl:

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.)

For a more robust solution, unpack the value into an 8-byte string and use the Math::Int64 module to convert it to an integer:

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);



回答2:


The solution was simple: added x4Q to skip four bytes before actual value; need to more visually think of padding/alignment..



来源:https://stackoverflow.com/questions/5488551/how-to-unpack-64-bit-unsigned-long-in-64-bit-perl

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!