/ / Ako rozbaliť (64-bitové) nepodpísané dlhé v 64-bitovom Perl? perl, 64bit, rozbaliť

Ako rozbaliť (64-bitové) nepodpísané dlhé 64-bitové Perl? perl, 64bit, rozbaliť

Pokúšam sa rozbaliť nepodpísanú dlhú hodnotu, ktorá sa odovzdáva z programu C do skriptu Perl cez SysV :: IPC.

Je známe, že hodnota je správna (urobil somtest, ktorý odošle rovnakú hodnotu do dvoch frontov, jeden čítaný Perlom a druhý aplikáciou C) a všetky predošlé hodnoty sa správne prečítajú (použité q namiesto i! pracovať so 64-bitovými celými číslicami).

Je tiež známe, že PHP mal niečo podobné v chybách (hľadať "nepodpísané dlhé na 64 bitových strojoch") (zdá sa byť podobný: Zabalte / rozbaľte 64-bitový int na 64-bitovej architektúre v PHP)

Doteraz testované argumenty:

  • ..Q (= nejaká hodnota, ktorá je väčšia, ako sa očakávalo)
  • .. L (= 0)
  • ..L! (= veľká hodnota)
  • (= 0)
  • ..l! (= veľká hodnota)
  • ..lN! (= 0)
  • ..N, ..N! (= 0)

use bigint; use bignum; -- bez efektu.

podrobnosti:

  • sizeof(unsigned long) = 8;
  • Data::Dumper->new([$thatstring])->Useqq(1)->Dump(); veľa nulových bajtov pozdĺž niektorých zmysluplných ..
  • byteorder = "12345678";

Riešenie: - x4Q s výplňou štyri bajty.

odpovede:

3 pre odpoveď č. 1

Rozbalenie pomocou Q v šablóny pracuje mimo krabice, ak máte 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.)

Pre robustnejšie riešenie rozbaľte hodnotu na 8-bytový reťazec a použite Math::Int64 modul pre konverziu na celé číslo:

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 pre odpoveď č. 2

Riešenie bolo jednoduché: pridané x4Q preskočiť štyri bajty pred aktuálnou hodnotou; je potrebné viac vizuálne myslieť na polstrovanie / zarovnanie ..