【问题标题】:In C#, how do I convert void* (pointing to a managed heap) to an object?在 C# 中,如何将 void*(指向托管堆)转换为对象?
【发布时间】:2018-06-14 03:44:04
【问题描述】:

我有一个 void* 指向堆上的某个托管对象。
如何将 void* 值转换为 object(指向同一事物,而不是副本)?

请注意,这不是 C# - How To Convert Object To IntPtr And Back? 的副本,因为我没有可以转换回 GCHandleGCHandle.ToIntPtr 的输出——我有一个对象的实际地址。

【问题讨论】:

标签: c# pointers


【解决方案1】:

您尝试做的事情在许多层面上都是错误的...如果托管对象未固定,则 GC 可以随时移动它,因此您的 void* 将变为非法。

但是你提出了一个问题。我会给你绳子让你上吊。

[StructLayout(LayoutKind.Explicit)]
public struct ObjectToIntPtr
{
    [FieldOffset(0)]
    public object[] Objects;
    [FieldOffset(0)]
    public IntPtr[] Ptrs;
}

然后:

var array = new int[] { int.MaxValue, 1, 2, 3 };

IntPtr ptr = new ObjectToIntPtr { Objects = new[] { array } }.Ptrs[0];

int[] array2 = (int[])new ObjectToIntPtr { Ptrs = new[] { ptr } }.Objects[0];

你想要的是最后一行。请注意,我在ObjectToIntPtr 中使用数组,因为.NET 运行时不喜欢我尝试使用object 加上IntPtr 执行struct,但如果它们是数组,则没有问题. sizeof(object) == sizeof(IntPtr) 所以即使在那里也没有问题(new object[10] 使用的内存与new IntPtr[10] 使用的内存相同。

【讨论】:

  • 好主意!如果我找不到其他东西,我可能会走这条路。 你试图做的事情在很多层面上都是错误的......我知道,整个场景甚至更奇怪,但它是一个 .NET 内存研究的东西,而不是电力银行或航空的东西,所以应该不错。
猜你喜欢
  • 2017-08-16
  • 2011-02-06
  • 2021-07-22
  • 2019-06-15
  • 1970-01-01
  • 2011-10-16
  • 2011-10-27
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多