如何获取 C# 对象上的非托管指针?
How to get unmanaged pointer on an C# object?
我知道如何在结构上创建非托管指针。
但我想要一个指向对象的非托管指针。
我已经知道我需要使用
保护对象不受 GC 的影响
GCHandle.Alloc(...);
但是我找不到定义指针的方法...
我认为您对 Marshal.StructureToPtr
感兴趣。我还建议阅读此 blog post.
尝试将 GCHandle.Alloc
与第二个参数 GCHandleType.Pinned
结合使用。方法 GCHandle.AddrOfPinnedObject
也可能有帮助。
试试这两个链接:
您可以固定这样的实例:
GCHandle handle = GCHandle.Alloc(oldList, GCHandleType.Pinned);
假设它有效,然后您可以将固定对象的地址作为与类型无关的指针,如下所示:
IntPtr ptr = handle.AddrOfPinnedObject();
不要忘记在失去对句柄的跟踪之前显式释放句柄(否则对象将保持永久固定状态):
handle.Free();
请注意我说的是 "assuming it works" — 并非所有对象都可以固定,不能固定的对象会在您尝试固定它们时抛出异常。
如果您想冒险获取非固定对象的地址,您可以使用 System.Runtime.CompilerServices.Unsafe
来尝试这样的事情:
static unsafe void* VeryUnsafeGetAddress(this object obj)
{
return *(void**)Unsafe.AsPointer(ref obj);
}
我知道如何在结构上创建非托管指针。
但我想要一个指向对象的非托管指针。
我已经知道我需要使用
保护对象不受 GC 的影响GCHandle.Alloc(...);
但是我找不到定义指针的方法...
我认为您对 Marshal.StructureToPtr
感兴趣。我还建议阅读此 blog post.
尝试将 GCHandle.Alloc
与第二个参数 GCHandleType.Pinned
结合使用。方法 GCHandle.AddrOfPinnedObject
也可能有帮助。
试试这两个链接:
您可以固定这样的实例:
GCHandle handle = GCHandle.Alloc(oldList, GCHandleType.Pinned);
假设它有效,然后您可以将固定对象的地址作为与类型无关的指针,如下所示:
IntPtr ptr = handle.AddrOfPinnedObject();
不要忘记在失去对句柄的跟踪之前显式释放句柄(否则对象将保持永久固定状态):
handle.Free();
请注意我说的是 "assuming it works" — 并非所有对象都可以固定,不能固定的对象会在您尝试固定它们时抛出异常。
如果您想冒险获取非固定对象的地址,您可以使用 System.Runtime.CompilerServices.Unsafe
来尝试这样的事情:
static unsafe void* VeryUnsafeGetAddress(this object obj)
{
return *(void**)Unsafe.AsPointer(ref obj);
}