【问题标题】:Delphi pointer arithmeticDelphi 指针算法
【发布时间】:2010-11-29 12:52:37
【问题描述】:

这行代码应该怎么写才能让它编译

MoveMemory(poleFileDescriptorW
         , (oleDataPointer + SizeOf(oleFileDescriptorW) *Index + 4)^
         , SizeOf(oleFileDescriptorW));

尤其是这部分

(oleDataPointer + SizeOf(oleFileDescriptorW)*Index + 4)^

我只想将指针移动SizeOf(oleFileDescriptorW)*Index + 4 字节

变量定义为:

pOLEFileDescriptorW : ^FILEDESCRIPTORW;
oleDataPointer : Pointer;

【问题讨论】:

  • 你使用的变量有哪些类型?

标签: delphi


【解决方案1】:

转换为整数类型,计算并转换回。

我通常使用Cardinal,但我认为这不适用于 64 位编译器。

Pointer(NativeInt(oleDataPointer) + SizeOf(oleFileDescriptorW)*Index + 4)

【讨论】:

  • 仍然没有64位版本的Delphi吗?我仍然希望我的代码能够与未来的 64 位 delphi 编译器(或 64 位 freepascal)一起使用
  • @CodeInChaos:可以使用NativeUInt类型。
  • 您可以使用 PByte(或 PAnsiChar)并以这种方式直接进行指针运算
  • Delphi > 2009 最终允许指针算术,只需将 $POINTERMATH 设置为 ON。
  • AFAIK NativeInt 是在 D2007 中引入的,但那里的声明是错误的(64 位)。它应该在 D2009 中修复(我跳过了它,所以我无法检查)。
【解决方案2】:

如果您使用的是 DELPHI >= 2009,请将 $POINTERMATH 设置为 ON,您可以直接使用指针运算

【讨论】:

    【解决方案3】:

    MoveMemory 和相同的 CopyMemory 函数接受 指针,而不是变量,因为 Delphi RTL 函数 Move 需要(这是 MoveMemoryMove 之间的唯一区别)。

    所以你不应该取消引用指针。做吧

    MoveMemory(poleFileDescriptorW,
               (oleDataPointer + SizeOf(oleFileDescriptorW)*Index + 4),
               SizeOf(oleFileDescriptorW));
    

    其中每个参数都是一个指针/基数。根据您的实际数据类型,您可能需要进行一些简单的转换。例如,您可能需要使用PSomeType(cardinal(myPointer) + cardinal(myPointer2))

    无论如何,如果您有时需要取消引用指针,则需要指定其类型。

    (oleDataPointer + SizeOf(oleFileDescriptorW)*Index + 4)^
    

    不可能工作(为什么?)。做

    PMyType(cardinal(oleDataPointer) + SizeOf(oleFileDescriptorW)*Index + 4)^
    

    【讨论】:

      【解决方案4】:

      类型转换为整数。

       Pointer(Integer(oleDataPointer) + SizeOf(oleFileDescriptionW) * Index + 4)
      

      Andreas 是正确的,您应该直接使用指针。 看看这是否有效。

      上帝保佑

      【讨论】:

      • 你应该投到cardinal,而不是integer(为什么?)!此外,MoveMemory/CopyMemory 需要指针,而不是变量,因此您不应取消引用(如 Move 的情况)。
      • 我更喜欢无符号整数类型,但这主要是一个风格问题。但是如果整数溢出检查开启(默认关闭),您的代码可能会失败
      • @andreas 为什么不是整数? Delphi 是否进行转换并在溢出时丢失数据?
      • @codeinchaos 哦,我明白了。感谢您的解释,不记得 Delphi 检查整数溢出的可能性。
      • 这在实践中并不重要,因为在实践中进行指针作为整数/基数和 int 溢出检查无论如何都不能很好地工作。所以你应该在这些代码部分禁用这些检查。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-04-01
      • 1970-01-01
      • 2023-04-06
      相关资源
      最近更新 更多