C#内存地址和variables

在C#中,有没有办法

  1. 获取存储在引用typesvariables中的内存地址?
  2. 获取variables的内存地址?

编辑:

int i; int* pi = &i; 
  • 你如何打印pi的hex值?

对于#2, &运算符将以与C相同的方式工作。如果variables不在堆栈中,那么在工作时可能需要使用fixed语句将其fixed ,以便垃圾收集器不会移动它,虽然。

对于#1,引用types更棘手:你需要使用GCHandle ,并且引用types必须是blittable,即具有定义的内存布局,并且可以按位复制。

为了访问地址作为一个数字,你可以从指针types转换为IntPtr (一个整数types定义为与指针相同的大小),并从那里到uintulong (取决于底层机器的指针大小)。

 using System; using System.Runtime.InteropServices; [StructLayout(LayoutKind.Sequential)] class Blittable { int x; } class Program { public static unsafe void Main() { int i; object o = new Blittable(); int* ptr = &i; IntPtr addr = (IntPtr)ptr; Console.WriteLine(addr.ToString("x")); GCHandle h = GCHandle.Alloc(o, GCHandleType.Pinned); addr = h.AddrOfPinnedObject(); Console.WriteLine(addr.ToString("x")); h.Free(); } } 

数字1是不可能的,你不能有一个指向pipe理对象的指针。 但是,可以使用IntPtr结构来获取有关引用中指针地址的信息:

 GCHandle handle = GCHandle.Alloc(str, GCHandleType.Pinned); IntPtr pointer = GCHandle.ToIntPtr(handle); string pointerDisplay = pointer.ToString(); handle.Free(); 

对于数字2,您使用&运算符:

 int* p = &myIntVariable; 

指针当然必须在不安全的块中完成,并且必须在项目设置中允许不安全的代码。 如果variables是一个方法中的局部variables,它将被分配到堆栈中,所以它已经被修复了,但是如果variables是一个对象的成员,那么必须使用fixed关键字将这个对象fixed在内存中,这样它才不会被移动垃圾收集器。

最正确地回答你的问题:

#1是可能的,但有点棘手,应该只是为了debugging的原因:

 object o = new object(); TypedReference tr = __makeref(o); IntPtr ptr = **(IntPtr**)(&tr); 

这适用于任何对象,实际上将内部指针返回到内存中的对象。 请记住,由于GC喜欢在内存中移动对象,因此地址可能会随时更改。

#2指针不是对象,因此不会从它们inheritanceToString 。 您必须将指针转换为IntPtr,如下所示:

 Console.WriteLine((IntPtr)pi);