Win64异常,Win32没有例外

时间:2016-05-15 18:46:40

标签: delphi 32bit-64bit

var
  APoints: array [0 .. 3] of Integer;
  AptX, AptY: array [0 .. 3, 1 .. 32] of Integer;
  AptP, AptU: array [0 .. 3, 1 .. 32] of Single;
  AHistory: array [0 .. 3, Byte] of Integer;
  AMaxHistory: array [0 .. 3] of Integer;
  ALUT: array [0 .. 3, 0 .. 255] of Byte;
  APoint, AColorIndex: Integer;
  AImage, AIEBitmap: TIEBitmap;
  AImageLoaded: Boolean;
  ACurvesPath: String;

function CompareNatural(s1, s2: String): Integer;
  function ExtractNr(n: Integer; var Txt: String): Int64;
  begin
    while (n <= Length(Txt)) and (Txt[n] >= '0') and (Txt[n] <= '9') do
      n := n + 1;
    Result := StrToInt64Def(Copy(Txt, 1, n - 1), 0);
    Delete(Txt, 1, (n - 1));
  end;

var
  iB: Boolean;
begin
  Result := 0;
  s1 := LowerCase(s1);
  s2 := LowerCase(s2);
  if (s1 <> s2) and (s1 <> '') and (s2 <> '') then
  begin
    iB := False;
    while (not iB) do
    begin
      if ((s1[1] >= '0') and (s1[1] <= '9')) and
        ((s2[1] >= '0') and (s2[1] <= '9')) then
        Result := Sign(ExtractNr(1, s1) - ExtractNr(1, s2))
      else
        Result := Sign(Integer(s1[1]) - Integer(s2[1]));
      iB := (Result <> 0) or (Min(Length(s1), Length(s2)) < 2);
      if not iB then
      begin
        Delete(s1, 1, 1);
        Delete(s2, 1, 1);
      end;
    end;
  end;
  if Result = 0 then
  begin
    if (Length(s1) = 1) and (Length(s2) = 1) then
      Result := Sign(Integer(s1[1]) - Integer(s2[1]))
    else
      Result := Sign(Length(s1) - Length(s2));
  end;
end;

function SortMe(List: TStringList; i1, i2: Integer): Integer;
begin
  Result := CompareNatural(List[i1], List[i2]);
end;

function CalcImgSize(w, h, tw, th: Integer): TPoint;
begin
  Result := Point(0, 0);
  if (w = 0) or (h = 0) then
    Exit;
  if (w < tw) and (h < th) then
    Result := Point(w, h)
  else
  begin
    if w > h then
    begin
      if w < tw then
        tw := w;
      Result := Point(tw, Trunc(tw * h / w));
      if Result.Y > th then
        Result := Point(Trunc(th * w / h), th);
    end
    else
    begin
      if h < th then
        th := h;
      Result := Point(Trunc(th * w / h), th);
      if Result.X > tw then
        Result := Point(tw, Trunc(tw * h / w));
    end;
  end;
end;

function Blend(Color1, Color2: TColor; A: Byte): TColor;
var
  c1, c2: LongInt;
  R, G, B, v1, v2: Byte;
begin
  A := Round(2.56 * A);
  c1 := ColorToRGB(Color1);
  c2 := ColorToRGB(Color2);
  v1 := Byte(c1);
  v2 := Byte(c2);
  R := A * (v1 - v2) shr 8 + v2;
  v1 := Byte(c1 shr 8);
  v2 := Byte(c2 shr 8);
  G := A * (v1 - v2) shr 8 + v2;
  v1 := Byte(c1 shr 16);
  v2 := Byte(c2 shr 16);
  B := A * (v1 - v2) shr 8 + v2;
  Result := (B shl 16) + (G shl 8) + R;
end;

procedure BilinearRescale(Src, Dest: TIEBitmap);
var
  X, Y, px, py: Integer;
  i, x1, x2, z, z2, iz2: Integer;
  w1, w2, w3, w4: Integer;
  Ratio: Integer;
  sDst, sDstOff: Integer;
  PScanLine: array of PRGBArray;
  Src1, Src2: PRGBArray;
  C, c1, c2: TRGB24;
begin
  if (Dest.Width < 2) or (Dest.Height < 2) then
  begin
    Dest.Assign(Src);
    Exit;
  end;
  SetLength(PScanLine, Src.Height);
  PScanLine[0] := (Src.Scanline[0]);
  i := Integer(Src.Scanline[1]) - Integer(PScanLine[0]);
  for Y := 1 to Src.Height - 1 do
    PScanLine[Y] := PRGBArray(Integer(PScanLine[Y - 1]) + i);
  sDst := Integer(Dest.Scanline[0]);
  sDstOff := Integer(Dest.Scanline[1]) - sDst;
  Ratio := ((Src.Width - 1) shl 15) div Dest.Width;
  py := 0;
  for Y := 0 to Dest.Height - 1 do
  begin
    i := py shr 15;
    if i > Src.Height - 1 then
      i := Src.Height - 1;
    Src1 := PScanLine[i];
    if i < Src.Height - 1 then
      Src2 := PScanLine[i + 1]
    else
      Src2 := Src1;
    z2 := py and $7FFF;
    iz2 := $8000 - z2;
    px := 0;
    for X := 0 to Dest.Width - 1 do
    begin
      x1 := px shr 15;
      x2 := x1 + 1;
      c1 := Src1[x1];
      c2 := Src2[x1];
      z := px and $7FFF;
      w2 := (z * iz2) shr 15;
      w1 := iz2 - w2;
      w4 := (z * z2) shr 15;
      w3 := z2 - w4;
      C.R := (c1.R * w1 + Src1[x2].R * w2 + c2.R * w3 + Src2[x2].R * w4) shr 15;
      C.G := (c1.G * w1 + Src1[x2].G * w2 + c2.G * w3 + Src2[x2].G * w4) shr 15;
      C.B := (c1.B * w1 + Src2[x2].B * w2 + c2.B * w3 + Src2[x2].B * w4) shr 15;
      PRGBArray(sDst)[X] := C;
      Inc(px, Ratio);
    end;
    sDst := sDst + sDstOff;
    Inc(py, Ratio);
  end;
  SetLength(PScanLine, 0);
end;

function PtInCircle(cx, cy, X, Y, radius: Integer): Boolean;
begin
  Result := ((cx - X) * (cx - X)) + ((cy - Y) * (cy - Y)) <= radius * radius;
end;

procedure WuLine(Src: TBitmap; x1, y1, x2, y2: Integer; Color: TColor);
var
  C: Cardinal;
  R, G, B: Byte;
  i, dx, dy, X, Y, w, h, a1, a2: Integer;
  dxi, dyi, iGradient: Integer;
  iLine: array of PRGBArray;
  function BlendPixel(X, Y, A: Integer): TRGB24;
  begin
    Result.R := A * (R - iLine[Y][X].R) shr 8 + iLine[Y][X].R;
    Result.G := A * (G - iLine[Y][X].G) shr 8 + iLine[Y][X].G;
    Result.B := A * (B - iLine[Y][X].B) shr 8 + iLine[Y][X].B;
  end;
begin
  C := ColorToRGB(Color);
  R := C and 255;
  G := (C shr 8) and 255;
  B := (C shr 16) and 255;
  w := Src.Width;
  h := Src.Height;
  if (x1 = x2) or (y1 = y2) then
  begin
    Src.Canvas.Pen.Color := Color;
    Src.Canvas.MoveTo(x1, y1);
    Src.Canvas.LineTo(x2, y2);
    Exit;
  end;
  // make an array of source scanlines to speed up the rendering
  SetLength(iLine, Src.Height);
  iLine[0] := (Src.Scanline[0]);
  i := Integer(Src.Scanline[1]) - Integer(iLine[0]);
  for Y := 1 to Src.Height - 1 do
    iLine[Y] := PRGBArray(Integer(iLine[Y - 1]) + i);
  dx := abs(x2 - x1);
  dy := abs(y2 - y1);
  if dx > dy then
  begin // horizontal or vertical
    if y2 > y1 then
      dy := -dy;
    iGradient := dy shl 8 div dx;
    if x2 < x1 then
    begin
      i := x1;
      x1 := x2;
      x2 := i;
      dyi := y2 shl 8;
    end
    else
    begin
      dyi := y1 shl 8;
      iGradient := -iGradient;
    end;
    if x1 >= w then
      x2 := w - 1;
    for X := x1 to x2 do
    begin
      Y := dyi shr 8;
      if (X < 0) or (Y < 0) or (Y > h - 2) then
        Inc(dyi, iGradient)
      else
      begin
        a1 := dyi - Y shl 8;
        a2 := 256 - a1;
        iLine[Y][X] := BlendPixel(X, Y, a1);
        iLine[Y + 1][X] := BlendPixel(X, Y + 1, a2);
        Inc(dyi, iGradient);
      end;
    end;
  end
  else
  begin
    if x2 > x1 then
      dx := -dx;
    iGradient := dx shl 8 div dy;
    if y2 < y1 then
    begin
      i := y1;
      y1 := y2;
      y2 := i;
      dxi := x2 shl 8;
    end
    else
    begin
      dxi := x1 shl 8;
      iGradient := -iGradient;
    end;
    if y2 >= h then
      y2 := h - 1;
    for Y := y1 to y2 do
    begin
      X := dxi shr 8;
      if (Y < 0) or (X < 0) or (X > w - 2) then
        Inc(dxi, iGradient)
      else
      begin
        a1 := dxi - X shl 8;
        a2 := 256 - a1;
        iLine[Y][X] := BlendPixel(X, Y, a2);
        iLine[Y][X + 1] := BlendPixel(X + 1, Y, a1);
        Inc(dxi, iGradient);
      end;
    end;
  end;
end;

在BGB区域过程中PRGBArray(sDst)[X]:= C时发生win64异常,但由于win64可能存在其他问题。

1 个答案:

答案 0 :(得分:3)

你错误认为整数和指针是一回事。

它们不是,也从未是同一件事。

指针的大小取决于CPU中的可寻址内存。它已经从16位变为20位到32位,现在是64位(尽管实际上只使用了48位)。

整数也取决于实现,但与CPU最容易使用的大小相匹配。

这已经从16位变为32位,现在是...... 32位。

它是32位,因为移动32位比一直操作64位更快。

永远不要假设sizeof(integer) = sizeof(pointer),因为您的代码会中断。

为那些天真地认为指针和整数在某种程度上相同的人解决问题。 Emba引入了NativeInt,它被定义为一个与指针大小相同的整数。

不幸的是,编译器通过允许您将一个整数强制转换为指针来帮助和滥用这种愚蠢行为,即使它们的大小不同。当你试图这样做时,它应该真的会产生编译器错误,但事实并非如此。

您需要将所有假integer替换为NativeInt或将假integer替换为pointer,并使用{$PointerMath on}编译器开关启用pointermath。

再也不要假设整数和指针有某种关联。

进一步阅读:

Converting 32-bit Delphi Applications to 64-bit Windows

Pointer Math (Delphi)

A hidden feature of $POINTERMATH directive in Delphi 2009

When can ((Pointer)(P)+1)^ work?