C#不安全代码固定指针作为参数传递

前端之家收集整理的这篇文章主要介绍了C#不安全代码固定指针作为参数传递前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我在msdn上遇到了以下代码
  1. unsafe static void SquarePtrParam (int* p)
  2. {
  3. *p *= *p;
  4. }
  5.  
  6. unsafe static void Main()
  7. {
  8. Point pt = new Point();
  9. pt.x = 5;
  10. pt.y = 6;
  11. // Pin pt in place:
  12. fixed (int* p = &pt.x)
  13. {
  14. SquarePtrParam (p);
  15. }
  16. // pt now unpinned.
  17. Console.WriteLine ("{0} {1}",pt.x,pt.y);
  18. }

我只是想知道,我们是直接访问SquarePtrParam函数中的指针,它是否继承了从调用方法修复数组的信息?

为什么我们不需要在SquarePtrParam中将其明确设置为本地修复.

我想我可以使用一些关于这个固定语句的详细说明.

解决方法

固定语句实现unpin内存区域的方式与“using”语句关闭打开的文件一样使用(FileStream stream = new FileStream(..))构造.在您离开固定代码块之前,内存将被固定.

在IL代码中,它将创建虚拟PINNED局部变量并将指针存储到其中.这将不允许GC移动内存区域包含此指针.在您离开固定块后,它将零存储到此PINNED变量中.像这样:

  1. public static unsafe void TestInternal(byte* pointer)
  2. {
  3. Console.WriteLine((IntPtr)pointer);
  4. }
  5.  
  6. public static void FixedDemo()
  7. {
  8. Byte[] newArray = new Byte[1024];
  9.  
  10. unsafe
  11. {
  12. fixed (Byte* pointer = &newArray[0])
  13. {
  14. TestInternal(pointer);
  15. }
  16. }
  17.  
  18. Console.WriteLine("Test Complete");
  19. }

所以IL Code中的FixedDemo:

  1. .method public hidebysig static void FixedDemo() cil managed
  2. {
  3. // Code size 47 (0x2f)
  4. .maxstack 2
  5. .locals init ([0] uint8[] newArray,[1] uint8& pinned pointer)
  6. IL_0000: nop
  7. IL_0001: ldc.i4 0x400 // Put 1024 on the stack
  8. IL_0006: newarr [mscorlib]System.Byte // allocate new array of 1024 length
  9. IL_000b: stloc.0 // Store it in local variable 0
  10. IL_000c: nop
  11. IL_000d: ldloc.0 // Put local variable 0 on the stack
  12. IL_000e: ldc.i4.0 // Put zero on the stack
  13. IL_000f: ldelema [mscorlib]System.Byte // Load address of zero index from array
  14. IL_0014: stloc.1 // !!! Here we pin memory by storing it in pinned variable
  15. IL_0015: nop
  16. IL_0016: ldloc.1 // Load function argument
  17. IL_0017: conv.i // Perform conversion
  18. IL_0018: call void FinMath.Tests.Program::TestInternal(uint8*)
  19. IL_001d: nop
  20. IL_001e: nop
  21. IL_001f: ldc.i4.0 // Load zero on the stack
  22. IL_0020: conv.u // Perform conversion
  23. IL_0021: stloc.1 // !!!! Here we unpin memory
  24. IL_0022: nop
  25. IL_0023: ldstr "Test Complete" // Load string
  26. IL_0028: call void [mscorlib]System.Console::WriteLine(string) // Out message
  27. IL_002d: nop
  28. IL_002e: ret
  29. } // end of method Program::FixedDemo

欲了解更多信息,请访

> MSDN
> MSDN Magazine: Garbage Collection: Automatic Memory Management in the Microsoft .NET Framework
> Common language Runtime standard ECMA 335分区III,1.1.4.2管理指针(类型&)

猜你在找的C#相关文章