在C#中,有没有办法
获取存储在引用类型变量中的内存地址?
获取变量的内存地址?
编辑:
int i; int* pi = &i;
你如何打印出pi的十六进制值?
Jeffrey Hant.. 14
对于#2,&
运算符将以与C中相同的方式工作.如果变量不在堆栈中,则可能需要使用fixed
语句在工作时将其固定,因此垃圾收集器不会移动它.
对于#1,引用类型比较棘手:您需要使用a GCHandle
,并且引用类型必须是blittable,即具有已定义的内存布局并且是可按位复制的.
为了将地址作为数字访问,您可以从指针类型转换为IntPtr
(定义为与指针大小相同的整数类型),并从那里转换为uint
或ulong
(取决于底层机器的指针大小).
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(); } }
Guffa.. 5
数字1根本不可能,您不能拥有指向托管对象的指针.但是,您可以使用IntPtr结构来获取有关引用中指针地址的信息:
GCHandle handle = GCHandle.Alloc(str, GCHandleType.Pinned); IntPtr pointer = GCHandle.ToIntPtr(handle); string pointerDisplay = pointer.ToString(); handle.Free();
对于数字2,您使用&运算符:
int* p = &myIntVariable;
指针当然必须在不安全的块中完成,并且您必须在项目设置中允许不安全的代码.如果变量是方法中的局部变量,则它在堆栈上分配,因此它已经被修复,但如果变量是对象的成员,则必须使用fixed
关键字将该对象固定在内存中,以便它不被垃圾收集器.
对于#2,&
运算符将以与C中相同的方式工作.如果变量不在堆栈中,则可能需要使用fixed
语句在工作时将其固定,因此垃圾收集器不会移动它.
对于#1,引用类型比较棘手:您需要使用a GCHandle
,并且引用类型必须是blittable,即具有已定义的内存布局并且是可按位复制的.
为了将地址作为数字访问,您可以从指针类型转换为IntPtr
(定义为与指针大小相同的整数类型),并从那里转换为uint
或ulong
(取决于底层机器的指针大小).
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根本不可能,您不能拥有指向托管对象的指针.但是,您可以使用IntPtr结构来获取有关引用中指针地址的信息:
GCHandle handle = GCHandle.Alloc(str, GCHandleType.Pinned); IntPtr pointer = GCHandle.ToIntPtr(handle); string pointerDisplay = pointer.ToString(); handle.Free();
对于数字2,您使用&运算符:
int* p = &myIntVariable;
指针当然必须在不安全的块中完成,并且您必须在项目设置中允许不安全的代码.如果变量是方法中的局部变量,则它在堆栈上分配,因此它已经被修复,但如果变量是对象的成员,则必须使用fixed
关键字将该对象固定在内存中,以便它不被垃圾收集器.