如何在 C# 中获取 IntPtr 指针的属性
本文关键字:IntPtr 指针 属性 获取 | 更新日期: 2023-09-27 18:35:59
我在C#项目中使用了一些C++包装器。问题是我有一个指针hd
(类型IntPtr
)指向C++类型Head
,它具有一个名为xlong
的属性。我怎样才能得到那个属性?我知道两种方法:
var l = ((Head)Marshal.PtrToStructure(hd, typeof(Head))).xlong;
和
var l = ((Head*)hd.ToPointer())->xlong;
但是有没有办法直接使用元帅获得它?我没有找到任何关于它的信息。如果没有,我应该使用哪种方式?
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
结构是可 blitable 的,这意味着它对非托管代码和托管代码的表示形式完全相同。
因此,您可以使用最适合您的方法。您的第一种方法:
var l = ((Head)Marshal.PtrToStructure(hd, typeof(Head))).xlong;
优点是不需要您自己编写任何不安全的代码,而是让系统库来处理。
您的第二种方法:
var l = ((Head*)hd.ToPointer())->xlong;
具有在提取xlong
字段之前不会创建不必要的数据副本的优点。
正如Hans Passant指出的那样,通过使用Marshal.ReadIntPtr
,可以直接通过Marshal
类读取字段。这并不直接适用:它要求您首先计算偏移量。但是,Marshal
类已经包含一个为您执行此操作的方法:Marshal.OffsetOf
。
如果采用此方法,则可能需要将Marshal.OffsetOf
的结果缓存在static readonly
字段中,因为它永远不会更改,并且无需为每次访问再次计算它。