如何在 C# 中获取 IntPtr 指针的属性

How to get a property of an IntPtr pointer in C#

我在我的 C# 项目中使用了一些 C++ 包装器。问题是我有一个指向 C++ 类型 Head 的指针 hd(类型 IntPtr),它有一个名为 xlong 的属性。我怎样才能得到 属性?我知道两种方式:

var l = ((Head)Marshal.PtrToStructure(hd, typeof(Head))).xlong;

var l = ((Head*)hd.ToPointer())->xlong;

但是有什么方法可以直接使用 Marshal 获取它吗?我还没有找到任何相关信息。如果不是,我应该使用哪种方式?

Head 定义为

[StructLayout(LayoutKind.Sequential)]
public struct Head
{
    public int w;
    public int h;
    public double wmod;
    public double hmod;
    public IntPtr xlong;
    public IntPtr ylong;
    public int pitch;
    public uint flags;
}

一般来说,您的两种方法可能会产生不同的结果,但它不在这里:您的 Head 结构是 blittable,这意味着它对非托管代码和托管代码的表示是一模一样

因此,您可以使用最适合您的方法。你的第一个方法:

var l = ((Head)Marshal.PtrToStructure(hd, typeof(Head))).xlong;

优点是不需要您自己编写任何不安全的代码,而是由系统库来处理。

你的第二种方法:

var l = ((Head*)hd.ToPointer())->xlong;

的优点是在提取 xlong 字段之前不会制作不必要的数据副本。

直接通过 Marshal class 读取字段是可能的,正如 Hans Passant 指出的那样,通过使用 Marshal.ReadIntPtr. This is not directly suitable: it requires you to first calculate the offset. However, the Marshal class already contains a method that does that for you: Marshal.OffsetOf.

如果采用这种方法,您可能希望将 Marshal.OffsetOf 的结果缓存在 static readonly 字段中,因为它永远不会改变,并且无需为每个都重新计算访问。