Sun Feb 05 14:10:04 2012: Request 74578 was acted upon.
Transaction: Correspondence added by DOUGW
       Queue: Win32-API
     Subject: Win32::API::Struct alignment wrong
   Broken in: 0.64
    Severity: Normal
       Owner: Nobody
  Requestors: do...@cpan.org
      Status: open
 Ticket <URL: https://rt.cpan.org/Ticket/Display.html?id=74578 >


On Fri Feb 03 20:51:26 2012, rur...@x-ray.at wrote:
> Patch looks good. Aldo wanted to have that repeat bit fixed for a long
time.
> Thanks.
> 
> Now if you can repro the w64 align problem and send the output with
> debugging info, please?

Like I said before, I don't think 64-bit had anything to do with this
bug, as I was using a 32-bit perl and dll. I've been reading up on Win32
alignment and finally completely understand what needs to be done. My
test structure was suppose to start off with a char[10] and I thought it
was just a typo in the docs...now I see that it should have "xx" after
it in the pack/unpack. Attached is an updated patch, which correctly
fixes the repeat logic, and also I believe fixes the alignment of the
elements in the Struct (on closer look, the repeat logic is why the
alignments were wrong). It looks good just from calling getPack and
getUnpack. I'll test it with the actual dll on Monday.
--- Struct.pm   2012-02-03 15:39:35 -0800
+++ Struct.pm   2012-02-03 15:52:38 -0800
@@ -200,9 +200,10 @@
             $packing .= $subpacking;
             $packed_size += $subpacksize;
         } else {
+            my $repeat = 1;
             if($type =~ /\w\*(\d+)/) {
-                my $size = $1;
-                $type = "a$size";
+                $repeat = $1;
+                $type = "a$repeat";
             }
             
             DEBUG "(PM)Struct::getPack($self->{__typedef__}) ++ $type\n"; 
@@ -215,9 +216,9 @@
             }
             push(@recipients, $self);
             $type_size = Win32::API::Type::sizeof($orig);
-            $type_align = (($packed_size + $type_size) % $type_size);
+            $type_align = (($packed_size + $type_size) % $type_size);
             $packing .= "x" x $type_align . $type;
-            $packed_size += $type_size + $type_align;
+            $packed_size += ($type_size*$repeat) + $type_align;
         }
     }
 
@@ -253,32 +254,33 @@
     foreach my $member (@{ $self->{typedef} }) {
         ($name, $type, $orig) = @$member;
         if($type eq '>') {
-            my($subpacking, @subitems, $subpacksize) = 
$self->{$name}->getUnpack();            
+            my($subpacking, $subpacksize, @subitems) = 
$self->{$name}->getUnpack();            
             DEBUG "(PM)Struct::getUnpack($self->{__typedef__}) ++ 
$subpacking\n";
             $packing .= $subpacking;
             $packed_size += $subpacksize;          
             push(@items, @subitems);
         } else {
+            my $repeat = 1;
             if($type =~ /\w\*(\d+)/) {
-                my $size = $1;
-                $type = "Z$size";
+                $repeat = $1;
+                $type = "Z$repeat";
             }          
            DEBUG "(PM)Struct::getUnpack($self->{__typedef__}) ++ $type\n";
            $type_size = Win32::API::Type::sizeof($orig);
-           $type_align = (($packed_size + $type_size) % $type_size);
+           $type_align = (($packed_size + $type_size) % $type_size);
            $packing .= "x" x $type_align . $type;
-           $packed_size += $type_size + $type_align;
+           $packed_size += ( $type_size * $repeat ) + $type_align;
 
             push(@items, $name);
         }
     }
     DEBUG "(PM)Struct::getUnpack($self->{__typedef__}): unpack($packing, 
@items)\n";
-    return($packing, @items, $packed_size);
+    return($packing, $packed_size, @items);
 }
 
 sub Unpack {
     my $self = shift;
-    my($packing, @items) = $self->getUnpack();
+    my($packing, undef, @items) = $self->getUnpack();
     my @itemvalue = unpack($packing, $self->{buffer});
     DEBUG "(PM)Struct::Unpack: unpack($packing, buffer) = @itemvalue\n";
     foreach my $i (0..$#items) {

Reply via email to