在C#中,是否有一种方法可以:
- 获取存储在引用类型变量中的内存地址?
- 获取变量的内存地址?
编辑:
int i;
int* pi = &i;
- 如何打印出 pi 的十六进制值?
在C#中,是否有一种方法可以:
编辑:
int i;
int* pi = &i;
&
操作符的工作方式与 C 中相同。如果变量不在堆栈上,则可能需要使用 fixed
语句将其固定在您操作期间,以防垃圾收集器将其移动。GCHandle
,并且引用类型必须是可平坦化的,即必须有定义的内存布局并且可以按位复制。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();
}
}
object o = new object();
TypedReference tr = __makeref(o);
IntPtr ptr = **(IntPtr**)(&tr);
Console.WriteLine((IntPtr)pi);
第一点根本不可能实现,你不能拥有指向托管对象的指针。但是,你可以使用IntPtr结构来获取有关引用中指针地址的信息:
GCHandle handle = GCHandle.Alloc(str, GCHandleType.Pinned);
IntPtr pointer = GCHandle.ToIntPtr(handle);
string pointerDisplay = pointer.ToString();
handle.Free();
对于第二个数字,您可以使用&运算符:
int* p = &myIntVariable;
当涉及到指针时,必须在不安全的块中进行操作,并且需要在项目设置中允许使用不安全代码。如果变量是方法中的局部变量,则已经分配在堆栈上,因此已经固定,但如果变量是对象的成员,则需要使用fixed
关键字将该对象固定在内存中,以防止被垃圾收集器移动。
GCHandle.ToIntPtr
返回句柄本身的内部表示,而不是它所指向的对象的地址。如果为同一对象创建多个句柄,则GCHandle.ToIntPtr
将为每个句柄返回不同的结果。GCHandle.AddrOfPinnedObject
返回句柄所指向的对象的地址。有关详细信息,请参阅GCHandle.ToIntPtr vs. GCHandle.AddrOfPinnedObject。 - Antosha
int *
强制转换为IntPtr
即可实现。 - Jeffrey Hantin