【问题标题】:Is it possible to create pinned pointer in C#?是否可以在 C# 中创建固定指针?
【发布时间】:2016-02-24 13:39:22
【问题描述】:

是否可以像在C++/CLI 中的pin_ptr 一样在C# 中创建固定指针?

【问题讨论】:

  • 仅适用于某些结构类型的数组(intuintshortushortIntPtr...)和strings
  • C# 代码中 pin_ptr 的完全等价物是 fixed 关键字。它与固定指针不同,它使用更优化的方式告诉 GC 不要移动对象。只是抖动生成的元数据中的一个状态位,没有底层的 CLR 调用。但是你必须小心,一旦执行离开固定语句,指针就会变得无效。
  • @HansPassant pin_ptrfixed 更强大。使用pin_ptr,您可以固定任何东西,而使用fixed,您只能固定一些东西。

标签: c# pointers c++-cli


【解决方案1】:

一般解决方案:

GCHandle handle = GCHandle.Alloc(myObject, GCHandleType.Pinned);
try
{
    IntPtr myPinnedPointer = handle.AddrOfPinnedObject();
    // use myPinnedPointer for your needs
}
finally
{
    handle.Free();
}

特殊情况:

如果你的对象是一个结构体的数组或者是一个字符串,并且你可以在你的项目中使用不安全的代码,你可以使用fixed上下文:

unsafe
{
    fixed (char* myPinnedPointer = myString)
    {
        // use myPinnedPointer for your needs
    }
}

【讨论】:

  • 试试myObject = new object()看看会发生什么:-)
  • @xanatos:对象不包含数据,因此通过固定指针访问其内容没有意义。并且myObject 也不允许包含其他引用类型。所以这当然只适用于具有 blittable 成员的对象。
  • 重点是不允许包含其他引用类型(并且不允许作为我要添加的引用类型,除了数组或@987654326 @)
【解决方案2】:

虽然在 C# 中有 fixed 关键字,并且您可以使用 System.GCHandle 结构,但没有任何东西具有 pin_ptr<> 的“力量”。使用pin_ptr<>,您可以固定任何托管对象,而使用fixed,您只能固定strings 或不包含引用类型的值类型数组。所以你可以固定int[],或MyEnum[],或MyStructWithoutReferenceTypes[],但不能固定MyClassTypeMyClassType[]

【讨论】:

  • pin_ptr 没有额外的魔力,它仍然需要是一个 blittable 值类型。
  • @HansPassant 你确定吗?因为pin_ptr<List<String^>^> pinned(&obj) 编译运行。
  • @HansPassant 来自msdn可以固定托管类的对象或子对象,在这种情况下,公共语言运行时不会在垃圾回收期间移动它
  • Hmya,它可以编译,但你接下来要做什么?你不能用那个指针做任何事情。
  • 一个不能解引用的指针就像一个回不来的回旋镖。这是一根棍子。
猜你喜欢
  • 2020-01-18
  • 1970-01-01
  • 2020-12-26
  • 2010-10-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多