ali*_*hoo 5 .net c# pointers memory-management memory-address
我设法得到一个.net对象的地址
GCHandle objHandle = GCHandle.Alloc(obj,GCHandleType.WeakTrackResurrection);
int address = GCHandle.ToIntPtr(objHandle).ToInt32();
Run Code Online (Sandbox Code Playgroud)
我可以通过回忆起这个对象
Object obj = GCHandle.FromIntPtr(IntPtr(address)).Target;
Run Code Online (Sandbox Code Playgroud)
好吧,目的是将地址存储在本机类中,并具有哪个本机对象与哪个.net对象相关联的信息.
AFAIK地址不会因为分配而改变,是真的还是有人有更好的想法来实现我的目的?
谢谢
你需要固定GCHandle以阻止物体四处移动,因为GC会移动物体,因此未固定的指针可能会变得无效.固定对象会阻止它移动:
GCHandle handle = GCHandle.Alloc(obj, GCHandleType.Pinned);
IntPtr ptr = handle.AddrOfPinnedObject();
Run Code Online (Sandbox Code Playgroud)
完成后你还必须释放手柄:
handle.Free();
Run Code Online (Sandbox Code Playgroud)
正如Tim和thecoop所指出的那样,GCHandle.Alloc可能会阻止垃圾回收,但是实际对象地址可能会更改,因为GC可能会移动对象,除非您固定对象。此外,您的代码正在使用GCHandleType.WeakTrackResurrection,并且不会阻止垃圾回收。GCHandle.ToIntPtr将提供可以在非托管调用上往返的句柄地址。实际的对象地址将通过AddrOfPinnedObject方法给出。
话虽如此,IMO,您的代码可能用于将.NET对象与非托管对象相关联的目的。这是因为GCHandle.To/FromIntPtr会找回正确的GCHandle,并且您可以通过它访问.NET对象(前提是该对象未进行垃圾回收)。IMO,实际对象地址是否已更改应该无关紧要。