4

我继承了一个 Delphi 应用程序,但我对 object pascal 一无所知。

这是一个 BPL,我需要将其编译到新版本的 C++ Builder XE中。
当我运行 make 我得到错误:

E2064 左侧无法分配。

我已经学习了足够多的 obj pascal 来知道我有一个试图被赋值的常量。

但是,显然,您可以超越这种行为;本质上是通过进入 Delphi 编译器下的构建选项并打开“可分配类型常量”来将常量转换为变量。

我这样做了,我继续得到同样的错误。

我尝试用 {$J+} 和 {$J-} 包围我的代码,但它仍然无法编译。

procedure TChunkIDAT.CopyInterlacedRGB8(const Pass: Byte;
  Src, Dest, Trans{$IFDEF Store16bits}, Extra{$ENDIF}: pChar );
var
  Col: Integer;
 begin
 {Get first column and enter in loop}
 Col := ColumnStart[Pass];
 Dest := pChar(Longint(Dest) + Col * 3);
 repeat
 {Copy this row}

  Byte(Dest^) := fOwner.GammaTable[pByte(Longint(Src) + 2)^]; inc(Dest);

获取最后一行的错误。如果我将 const 更改为 var,则会收到声明与前一个声明不同的错误,但我不知道前一个声明在哪里......

4

3 回答 3

9

您正在将一个两字节的事物 ( Char) 类型转换为一个字节的事物 ( Byte)。读取该值很容易定义,但使该值可写却很棘手,可能出于同样的原因,正式和实际“var”参数的类型需要相同。

也许您想将其强制转换为两个字节的东西,例如Word. 或者,也许您想GammaTable成为一个数组,Char因此您根本不必进行类型转换。或者,如果这段代码最初是为早于 2009 年的 Delphi 版本编写的,那么您希望这些PChar声明是PAnsiChar- 字符类型变得更广泛。另一种选择是将类型Dest转换为PByte然后取消引用结果。不过,这可能是个坏主意,因为您只会覆盖缓冲区的所有其他字节。

根据函数的名称,听起来好像PChar从来都不是正确的数据类型。该类型用于字符数据,但我认为此代码正在处理bytes。正确的做法可能是更改PCharPByte,然后您根本不需要进行类型转换Dest

$J指令无关紧要;它控制编译器是否允许您为类型化常量赋值。您在此代码中没有任何这些。

于 2010-11-12T03:45:06.343 回答
2

原因是从 Delphi 2009 开始,Char、PChar 和 String 都是 Unicode,每个字符存储多个字节。
您不应该将这些指针转换为字节,如果您将赋值的左侧转换为字节,编译器会阻止您分配它们。

这编译:

procedure CopyInterlacedRGB8(const Pass: Byte; Dest: pAnsiChar); overload;
begin
  Byte(Dest^) := Pass;
end;

这不会:

procedure CopyInterlacedRGB8(const Pass: Byte; Dest: pChar); overload;
begin
  Byte(Dest^) := Pass;
end;

您应该使用 pByte 而不是 pChar,这会使代码更简单:

procedure CopyInterlacedRGB8(const Pass: Byte; Dest: PByte); overload;
begin
  Dest^ := Pass;
end;

——杰伦

于 2010-11-12T06:19:40.687 回答
1

看起来您正在使用 Gustavo Daud 的 TPngImage 库。您不需要在外部 BPL 中使用该代码,因为它自 D2009 以来已包含在 RTL 中。从 BPL 中删除该单元,您应该能够通过该PngImage单元获得更新版本。

于 2010-11-12T05:05:32.067 回答