【问题标题】:Delphi compiler error E2064 left side cannot be assigned toDelphi 编译器报错 E2064 左侧不能分配给
【发布时间】:2011-05-08 20:46:08
【问题描述】:

我继承了一个 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,则会收到声明与前一个声明不同的错误,但我不知道前一个声明在哪里......

【问题讨论】:

  • @jachguate 目标是 XE,所以它看起来像一个 Unicode 问题。
  • 我还没有意识到我的 38% 率。感谢您指出这一点,我会看看我是否可以解决这个问题。这是一个我没有写的包(来自 IOCOMP.com 的第 3 方)。它是 C++ Builder 6 中使用的第 3 方 VCL 控件集,我正在尝试为 CBuilder XE 编译,因为他们还没有 XE 版本的工具。

标签: delphi unicode c++builder delphi-xe


【解决方案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;

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

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

--杰罗恩

【讨论】:

  • 这看起来很有希望。我确实将很多 pChar 更改为 pAnsiChar 但我没有更改函数参数。我会试试这个并报告。
  • 那么整数在:Dest := pChar(Longint(Dest) + Col * 3); ???????
  • @LincesMarques 不会为您提供字节值,而是指向 16 位字符的指针。重复循环仍然会失败,因为它将指针增加 16 位,跳过部分 RGB 字节。
【解决方案2】:

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

【讨论】:

  • 不确定 - 你可能是正确的。我们使用的是 IOCOMP 的 VCL 工具 (iocomp.com)。
  • 您能详细说明如何解决这个问题吗?我似乎找不到 hpp 文件中包含 pngimage 的位置 // 帕斯卡单位 pngimage.hpp // (请勿编辑:机器生成的标头)'pngimage.pas' rev: 22.00 PNGImage.pas unit pngimage; pngzlib.pas {该单元将 ZLIB 链接到 pngimage 单元以实现 }
  • @Eric M:对不起,我不知道如何在 C++ Builder 端处理包和链接到 .pas 文件。也许您可以将其作为一个新问题提出?
  • 好的,自从我上一篇文章以来,我只是用 pngimage2、pngzlib2 和 pnglang2 重命名了 pngimage、pngzlib 和 pnglang 的所有副本。一切仍然可以正常编译,但是当我安装时,我收到与 JCONSTS 的冲突报告,并且它在同一个 vclimg150 库中。我在源代码树的任何地方都找不到引用的 jconsts。
  • @Eric M:在这里帮不了你太多,抱歉。我只是碰巧认出了 TChunkIDAT 这个名字,当时我经常使用 PngImage,然后它才被添加到 RTL。
【解决方案3】:

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

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

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

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

【讨论】:

  • 这是一些非常糟糕的代码。我猜编译器曾经容忍等号左侧的强制转换,但现在不再容忍了。我从来没有想过它会被容忍——作为一个程序员,我肯定不会容忍它。我知道他们已经关闭了一些不应该编译但确实编译的其他案例,也许这是另一个案例。
  • 编译器仍应容忍左侧强制转换,@Loren。有时它可能很有用,例如当您想在不触发引用计数的情况下分配接口变量的值时——只需将目标类型强制转换为Pointer。这里的问题是,从 Delphi 2009 开始,大小是不同的。
  • 回顾一下:(1)错误的代码?我没有写 (2) 我不知道 object pascal 是什么 (3) 它是来自 IOCOMP 的第 3 方 vcl 控件,显然还不支持 BuilderXE,我只是试图针对BuilderXE 下的运行时图像并且不知道帕斯卡对我来说是一个挑战。感谢您的反馈。
  • 我用所有 PChars 替换了 PBytes,现在我可以克服错误并让这个傻瓜编译和链接。但是,当我尝试安装生成的 BPL 时,我得到 IOCOMP65 包含单元 Pnglang,它也在包 vclimg150 中。调查上面的 cmets,我希望注释掉 pngimage,但我找不到它包含在哪里。有什么提示吗?
  • 打开 .DPK 包文件。项目管理器窗口应显示项目中的文件列表,包括 Pnglang。在列表中选择该项目并将其删除。如果您收到有关将 Pnglang 隐式添加到项目中的警告,请不要忽略它。要解决它,请将 vclimg150 添加到您的软件包的“需要”列表中。
猜你喜欢
  • 1970-01-01
  • 2010-10-11
  • 1970-01-01
  • 1970-01-01
  • 2014-07-03
  • 1970-01-01
  • 2011-10-04
  • 1970-01-01
  • 2021-05-06
相关资源
最近更新 更多