如何使变量在C#中永久固定?

如何使变量在C#中永久固定?,c#,.net,winforms,C#,.net,Winforms,在不安全的环境中,我知道通过使用fixed语句,我可以获取并锁定变量的地址,以便安全地使用获取的指针。但是,有没有办法安全地将指针存储在某个地方?如中所示,使该变量永久固定,直到指针本身被释放 例如,如果我想要一个指向整数/浮点/双精度的指针成为我的不安全类的成员,我该怎么办?固定内存的更持久解决方案是使用GCHandle类,如下所示: var handle = GCHandle.Create(myObject, GCHandleType.Pinned); IntPtr address = ha

在不安全的环境中,我知道通过使用
fixed
语句,我可以获取并锁定变量的地址,以便安全地使用获取的指针。但是,有没有办法安全地将指针存储在某个地方?如中所示,使该变量永久固定,直到指针本身被释放


例如,如果我想要一个指向
整数
/
浮点
/
双精度
的指针成为我的不安全类的成员,我该怎么办?

固定内存的更持久解决方案是使用
GCHandle
类,如下所示:

var handle = GCHandle.Create(myObject, GCHandleType.Pinned);
IntPtr address = handle.AddrOfPinnedObject();
//... use it
handle.Free();
这允许您检索固定对象的地址,并防止GC将其四处移动。但是,您必须保持
GCHandle
处于活动状态,并在完成后释放它。这比使用
fixed()
block更容易跨越许多方法甚至类

但是值得注意的是,固定内存可能会影响性能,因为这会使
GC
s更加努力


如果你需要一块永远不会被移动的内存,因为你正在使用它来与原生代码等进行互操作。你可以考虑使用<代码> McSal.AlxCGULL()/<代码>和<代码> McSal.FrutHGLULL()。这样您就可以分配不可移动的内存,而不会干扰

GC

固定内存的更持久的解决方案是使用
GCHandle
类,如下所示:

var handle = GCHandle.Create(myObject, GCHandleType.Pinned);
IntPtr address = handle.AddrOfPinnedObject();
//... use it
handle.Free();
这允许您检索固定对象的地址,并防止GC将其四处移动。但是,您必须保持
GCHandle
处于活动状态,并在完成后释放它。这比使用
fixed()
block更容易跨越许多方法甚至类

但是值得注意的是,固定内存可能会影响性能,因为这会使
GC
s更加努力


如果你需要一块不会移动的内存,因为你正在使用它来与原生代码进行互操作。你可以考虑使用<代码> MSEHAL.OLLCHGULL()/<代码>和<代码> McSal.FrutHGLULL()/code >,这样你就可以分配不受干扰的内存,它不会干扰<代码> GC/<代码>。< /P>这是为了什么?网络?形式?你能更详细地解释一下你想用它实现什么吗code@CR41G14这可能是问题的一部分,但标签清楚地表明了这一点。以老式的方式分配此类对象,并将其排除在托管视图之外,可能是明智的。固定托管对象会使垃圾收集器的工作复杂化,因此永久固定它们更糟糕。这只是一般的C#。我刚刚读完这篇关于fixed语句的文章:在fixed块中,我可以确信我持有的指针将指向正确的对象。但是,它只能在固定块内工作。我想做的是永久性地阻止系统移动一些对象,而不仅仅是在一小块代码中。这是为了什么?网络?形式?你能更详细地解释一下你想用它实现什么吗code@CR41G14这可能是问题的一部分,但标签清楚地表明了这一点。以老式的方式分配此类对象,并将其排除在托管视图之外,可能是明智的。固定托管对象会使垃圾收集器的工作复杂化,因此永久固定它们更糟糕。这只是一般的C#。我刚刚读完这篇关于fixed语句的文章:在fixed块中,我可以确信我持有的指针将指向正确的对象。但是,它只能在固定块内工作。我想做的是永久性地阻止系统移动一些对象,而不仅仅是在一小块代码中。如果myObject(创建方法中的第一个参数)是值类型,那么获得的地址是该对象的地址,还是该对象副本的地址?如何通过IntPtr访问底层对象?提前谢谢。我不认为myObject可以是值类型,如果您要传递一个struct对象,它将被装箱,因为GCHandle接受一个对象参数。你说不存在的物体是什么意思?您已经有了对对象的引用,因为您已将其固定。但是,如果您确定数据在类中的布局方式,则可以通过获取指针并将其移动一个偏移量来访问它。例如,对于数组,当您从AddOfPinnedObject()获取指针时,它将指向第一个元素,因此您可以通过这种方式使用指针访问数组元素。因此,如果我有一个已分配的值类型变量,并且我不希望它被移动,我可以使用GCHandle来执行此任务吗?@IcySnow以及此变量是如何分配的?因为如果它是在堆栈上创建的值类型变量(它是局部变量),则可以保证它不会被移动。如果它是另一个类对象中的一个字段,则必须锁定它,而不是结构本身,而是包含它的对象(类)。然后,有一个问题是知道结构在对象内部的偏移量,如果需要知道,请阅读StructLayout和FieldOffset属性。因此,如果我锁定引用类型的对象,并获取指向其值类型成员之一的不安全指针,然后,我可以安全地使用该指针,而不用担心系统将我的对象移动到其他地方,对吗?如果myObject(创建方法中的第一个参数)是值类型,那么获得的地址是该对象的地址,还是该对象副本的地址?如何通过IntPtr访问底层对象?提前谢谢。我不认为myObject可以是值类型,如果您要传递一个struct对象,它将被装箱,因为GCHandle接受一个对象参数。你说不存在的物体是什么意思?您已经有了对对象的引用,因为您已将其固定。但是,如果您确定数据是如何存储的