c#pointers vs IntPtr

Ali*_*ini 9 .net c# pointers

这是使用c#指针的第一个问题的第二部分

所以c#中的指针是"不安全的",并且不是由垃圾收集器管理,而IntPtr是一个托管对象.但为什么要使用指针呢?什么时候可以互换使用这两种方法?

Guf*_*ffa 8

一个IntPtr不能被用作一个指针的替代品.

IntPtr只包含一个数值,所以你不能用它来访问任何数据.由此得名; 它是一个与指针大小相同的整数值.您需要将值转换为指针以访问它指向的数据,因此在不使用不安全代码的情况下无法访问数据.

另请注意,这IntPtr是一个结构,而不是一个对象,因此垃圾收集器根本不直接关注它.

  • @Ali Tarhini:那只是调用一种方法,为你使用不安全的代码.关键是最后必须使用不安全的代码,否则无法访问数据. (3认同)
  • 实际上有使用编组 (2认同)

Dar*_*rov 7

IntPtr是一个托管对象,但它指向的对象仍然没有被垃圾回收.在C#中使用不安全的指针确实是你应该避免的.使用不安全指针的代码可能无法解释x86和x64系统之间内存地址的差异.它允许您轻松直接操作内存地址,这与IntPtr不同,因为您需要在指针和存储在此内存地址的实际结构之间进行编组.使用不安全的指针,你可以直接使用底层类型:这是我写的一篇博文,说明了一个可能使用的不安全指针.另一个常见示例是直接操纵图像像素.


Han*_*ant 7

CLI区分托管和非托管指针.键入托管指针,运行时已知指向值的类型,并且只允许类型安全的分配.非托管指针只能直接用于支持它们的语言,C++/CLI就是最好的例子.

相当于C#语言中的非托管指针是IntPtr.您可以使用强制转换来自由地来回转换指针.没有指针类型与它相关联,即使它的名称听起来像"指向int的指针",它相当于void*C/C++.使用这样的指针需要pinvoke,Marshal类或强制转换为托管指针类型.

一些代码可以使用:

using System;
using System.Runtime.InteropServices;

unsafe class Program {
    static void Main(string[] args) {
        int variable = 42;
        int* p = &variable;
        Console.WriteLine(*p);
        IntPtr raw = (IntPtr)p;
        Marshal.WriteInt32(raw, 666);
        p = (int*)raw;
        Console.WriteLine(*p);
        Console.ReadLine();
    }
}
Run Code Online (Sandbox Code Playgroud)

请注意unsafe关键字在这里是否合适.你可以致电Marshal.WriteInt64(),你不会得到任何投诉.它会破坏堆栈帧.

  • 这不是指针和`IntPtr`之间的区别.不必键入指针,它也可以是无类型指针,即"void*".区别在于`IntPtr`根本不是指针. (4认同)