C#的Marshal.ReadInt32(IntPtr)在Delphi中是什么意思?

3

我正在将一些C#代码翻译成Delphi,理解以下内容(msg = TMsg):

(int)msg.LParam

我认为这只是一个转换(如果我有错误,请纠正我),然而以下内容让我困惑:

Marshal.ReadInt32( (IntPtr)msg.WParam, 4 )

有人可以解释一下这个吗?


1
这是从指向int的指针中读取一个int。看起来是作为Windows消息的一部分,可能在WndProc覆盖中。 - Jodrell
1
我强烈建议您查看http://www.pinvoke.net/,那里有很多使用IntPtr、Int、WParam等的好例子。 - Erik Philips
2
@user539484 不是,但感谢您提供链接和点踩 (: - user497849
2
如果一个人对.NET和特别是Interop的处理完全不熟悉,即使是Marshal.ReadInt32的文档也可能无法完全解释清楚。上下文非常重要。 - David Heffernan
2
@user539484:在太阳(或月亮、星星)外面。 - Marjan Venema
显示剩余15条评论
1个回答

9

这只是从指针中读取一个4字节的整数。在托管的.net代码中,你没有指针(除非你使用不安全的代码),因此框架提供了工具来帮助本地代码和托管世界之间的互操作。.net库的MSDN文档是全面的,并且当然描述了Marshal.ReadInt32

这里的额外复杂性在于有额外的4字节偏移量。实际上,指针可能指向一个结构体,而这段代码正在挑选结构体偏移量为4的整数值。这很可能是代码之所以是这样的最有可能的解释。

现在,字面翻译如下:

PInteger(msg.WParam+4)^

但你也可以用Delphi这样写:
type
  TMyRecord = record
    i1: Integer;
    i2: Integer;
  end;
  PMyrecord = ^TMyRecord;
....
value := PMyRecord(msg.WParam)^.i2;

如果您知道这个 WParam 与哪个消息相关,则您也会知道在此处使用的真实 record 是什么。因此,您不需要定义专用记录,因为 Windows.pas 已经这样做了。

+1 谢谢David,所以这只是一个PInteger(msg.WParam)^吗?这就是我最初怀疑的,但对我来说不太清楚... - user497849
在托管代码中,你没有指针 - 这是错误的。如果你选择这样做,在我所使用的每种托管语言中都可以使用指针。 - Security Hound
@Dorin 不完全正确。有一个额外的偏移量。实际上是 PInteger(msg.WParam+4)^ - David Heffernan
@Ramhound 在不安全的代码中是可以的,但在安全的代码中不行。如果我错了,请指正我。如果您有更好的见解,请告诉我。 - David Heffernan
@David 是的,它是4字节的偏移量,谢谢! 顺便问一下,-1是什么意思?你的例子很好,你的评论也很完整!已接受! - user497849

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接