我继承了Delphi应用程序,我对object pascal一无所知。
我需要编译成新版本的C ++ Builder XE 。这是一个BPL。
当我运行make时,我得到错误:
E2064左侧无法分配。
我已经学会了足够多的obj pascal知道我有一个试图赋值的常量。
但是,显然,你可以超越这种行为;通过进入Delphi编译器下的Build选项并打开“Assignable Typed constants”,将常量转换为vars。我做到了,我继续得到同样的错误。
我尝试用{$ 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,那么我会得到声明与前一个声明不同但我不知道上一个声明在哪里的错误....
答案 0 :(得分:8)
你将一个双字节的东西(Char
)压缩成一个单字节的东西(Byte
)。 读取该值很容易定义,但是使该值可写很棘手,可能出于同样的原因,正式和实际“var”参数的类型必须相同。
也许你想把它输入到一个双字节的东西,比如Word
。或者您希望GammaTable
成为Char
的数组,因此您根本不需要进行类型转换。或者,如果此代码最初是为2009年之前的Delphi版本编写的,那么您希望那些PChar
声明为PAnsiChar
- 字符类型变得更宽。另一个选项是将Dest
输入到PByte
,然后 取消引用结果。不过,这可能是一个坏主意,因为你只会覆盖缓冲区的每个其他字节。
根据函数的名称,听起来PChar
永远不是正确的数据类型。该类型用于字符数据,但我认为此代码正在处理字节。正确的做法可能是将PChar
更改为PByte
,然后您根本不需要输入Dest
。
$J
指令无关紧要;它控制编译器是否允许您为键入的常量赋值。您没有此代码中的任何内容。
答案 1 :(得分:1)
看起来你正在和Gustavo Daud的TPngImage库合作。您不需要外部BPL中的代码,因为自D2009以来它已包含在RTL中。从BPL中删除该单元,您应该可以通过PngImage
单元获取更新版本。
答案 2 :(得分:1)
原因是,自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;
而不是pChar,你应该使用pByte,这使代码更简单:
procedure CopyInterlacedRGB8(const Pass: Byte; Dest: PByte); overload;
begin
Dest^ := Pass;
end;
- 的Jeroen