如何在 C# 中获取 IntPtr 指针的属性
Posted
技术标签:
【中文标题】如何在 C# 中获取 IntPtr 指针的属性【英文标题】:How to get a property of an IntPtr pointer in C# 【发布时间】:2015-01-02 11:23:10 【问题描述】:我在我的 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;
【问题讨论】:
与您的实际问题无关,但您的资源名称不会是long
。这是 C++ 和 C# 中的关键字。除此之外,它将(稍微)取决于Head
的定义。一般来说,你的两种方法不一定会给出相同的结果。如果您能展示您的 C# 类 Head
是如何定义的,将会很有帮助。
你是对的,属性是xlong
。 Head
实际上是一个结构。这是它的代码:pastebin.com/eTQC2u8D
谢谢,我冒昧地将其添加到您的问题中。
使用Marshal.ReadIntPtr()。使用 Marshal.OffsetOf() 计算偏移量,通常在静态构造函数中。
@HansPassant Heh,当您只指出ReadIntPtr
而尚未提及OffsetOf
时,我正在写我的答案。现在看起来有点傻。
【参考方案1】:
一般来说,您的两种方法可能会给出不同的结果,但它不在这里:您的 Head
结构是 blittable,这意味着它对非托管代码和托管代码的表示完全相同。
因此,您可以使用最适合您的方法。你的第一种方法:
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
字段中,因为它永远不会改变,也无需为每次访问重新计算。
【讨论】:
感谢您的解释!我想我会使用Marshal.ReadIntPtr
方法,因为它不需要不安全的代码并且(我想)它不需要在获取属性之前获取结构。再次感谢!
另外和shigtly无关,如果我只想提取一次字段,我应该使用第二种方法吗?
@user2223034 如果您只想这样做一次,请使用您最容易阅读和完全理解的任何一种形式。其中哪一个是我无法为您做出的决定。
好的,无论如何,目前看来我必须多次使用这些字段。谢谢。问候!以上是关于如何在 C# 中获取 IntPtr 指针的属性的主要内容,如果未能解决你的问题,请参考以下文章
我用C#,上一步函数返回了一个IntPtr型的图片指针,我已知图片的长、宽,如何转换成image类。
创建 COM 接口,返回一个在 C# 中编组为 IntPtr 的指针