【问题标题】:Delphi DX10.4 E2064 code does not compileDelphi DX10.4 E2064代码无法编译
【发布时间】:2020-09-01 09:08:36
【问题描述】:

我不是一个 Delphi 程序员,我很乐意做 C++Builder 编程,delphi 不是我的语言。我有一些用 Delphi 编写的组件,它们在 10.3 中编译良好,但在 10.4 中确实出现错误,我可以看到问题的原因,但我不知道如何修复它。请帮我解决它。

procedure CopyInterlacedRGB8(const Pass: Byte; Src, Dest, Trans, Extra: pChar)

    Dest^ := Char(fOwner.GammaTable[pByte(Longint(Src) + 2)^]); inc(Dest);  // changed these two, but I have no clue what I'm doing lul
    Dest^ := Char(fOwner.GammaTable[pByte(Longint(Src) + 1)^]); inc(Dest);
    Byte(Dest^) := fOwner.GammaTable[pByte(Longint(Src)    )^]; inc(Dest);  // ERROR here

我在这里看到的方式,正如我在 C++ 中所理解的那样,有一个字节正在初始化,并且正在被分配。类似于 char('a') = 5;但是我可以看到代码最初想要做什么,将一些东西分配给Dest的地址。

我应该如何改变这些东西才能正常工作??

【问题讨论】:

  • 你遇到了什么错误?
  • 您忘记告诉我们您收到了什么错误。但是,DestPChar,所以 Dest^Char。这是一个两字节的值,因此您不能将其转换为 Byte
  • 除非您处理 16/48 位 RGB,否则所有这些变量都只想处理字节,而不是字。使用PAnsiChar 而不是PChar - 你的函数名称无论如何都表示8bit。
  • 这段代码看起来有缺陷,即使你可以编译它。 Char 在您引用的两个版本中都是两个字节宽。除了让代码编译之外,您可能还想让它工作!
  • @AmigoJack OP 正在处理 RGB 字节数据。他们不应该使用CharPAnsiChar - 这些是字符和文本的字符串类型。 ByteTBytes 将是合适的。没有以pChar 为参数的明智解决方案,因此从根本上说,这种方法永远不会有用。如何为其设计替代品将取决于您所处的环境。选择合适的参数类型应该是第一步。

标签: delphi


【解决方案1】:

你没有给出GammaTable的声明。我创建了一个看起来合适的。我没有在这里初始化它,但它应该在你的代码中。如果你的声明不同,可能我的代码需要修改。

var
    GammaTable : array [Byte] of Byte;

procedure CopyInterlacedRGB8(const Pass: Byte; Src, Dest, Trans, Extra: pChar);
var
    BDest : PByte;
begin
    BDest  := PByte(Dest);
    BDest^ := GammaTable[PByte(UIntPtr(Src) + 2)^]; Inc(BDest);
    BDest^ := GammaTable[PByte(UIntPtr(Src) + 1)^]; Inc(BDest);
    BDest^ := GammaTable[PByte(UIntPtr(Src)    )^]; Inc(BDest);
end;

我没有更改函数的参数类型,但可以肯定 SrcDst 应该是 PByte 而不是 PChar。无论如何,我编写的代码将同样有效,只要它包含所需的源表和目标表。

我引入了BDest 变量以使代码更具可读性。

注意如果Src被声明为PByte{$POINTERMATH ON},那么代码可以简化:

PByte(UIntPtr(Src) + 2)^

变成

Src[2];

所以程序可以这样改写:

{$POINTERMATH ON}
procedure CopyInterlacedRGB8_(const Pass: Byte; Src, Dest : PByte; Trans, Extra: pChar);
begin
    Dest[0] := GammaTable[Src[2]];
    Dest[1] := GammaTable[Src[1]];
    Dest[2] := GammaTable[Src[0]];
end;

更具可读性,不是吗?

【讨论】:

  • PByte 声明时已启用 {$POINTERMATH ON},因此您无需在自己的代码中手动启用指针数学即可在 PByte 变量上使用指针数学。跨度>
  • @RemyLebeau 很高兴知道!
  • 我可能只是转储不必要的TransExtra 参数——至少在这个例子中它们完全没有意义。 OP 没有向我们展示任何需要它们的代码。
猜你喜欢
  • 2011-05-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-07-08
  • 2017-01-16
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多