究竟什么是IntPtr?

时间:2009-07-18 18:13:01

标签: c# intptr

通过使用IntelliSense并查看其他人的代码,我遇到了这种IntPtr类型;每次需要使用它时,我只需要放置nullIntPtr.Zero并找到大多数功能。究竟是什么以及何时/为何使用它?

8 个答案:

答案 0 :(得分:149)

这是“原生(特定于平台)的大小整数。”它在内部表示为void*,但是以整数形式公开。只要您需要存储非托管指针并且不想使用unsafe代码,就可以使用它。 IntPtr.Zero实际上是NULL(空指针)。

答案 1 :(得分:61)

这是一个足够大的值类型,用于存储本机或不安全代码中使用的内存地址,但不能直接用作安全托管代码中的内存地址。

您可以使用IntPtr.Size来确定您是在32位还是64位进程中运行,因为它将分别为4或8个字节。

答案 2 :(得分:39)

以下是一个例子:

我正在编写一个与高速摄像头连接的C#程序。相机有自己的驱动程序,可以自动获取图像并将它们加载到计算机的内存中。

因此,当我准备将最新的图像带入我的程序中时,相机驱动程序为我提供了一个IntPtr,以便将图像存储在物理内存中,因此我不必浪费时间/资源创建另一块内存来存储已经存储在内存中的图像。 IntPtr只显示图像已经存在的位置。

答案 3 :(得分:31)

直接解释

IntPtr 整数,其大小与指针相同。

您可以使用IntPtr将指针值存储在非指针类型中。此功能在.NET中很重要,因为使用指针非常容易出错,因此在大多数情况下都是非法的。通过允许指针值存储在“安全”数据类型中,不安全代码段之间的管道可以用更安全的高级代码实现 - 甚至可以用不支持的.NET语言实现直接支持指针。

IntPtr的大小是特定于平台的,但很少需要考虑这个细节,因为系统会自动使用正确的大小。

名称“IntPtr”令人困惑 - 像Handle这样的东西可能更合适。我最初的猜测是“IntPtr”是一个指针 一个整数。 MSDN documentation of IntPtr在没有提供关于名称含义的深入见解的情况下进入了一些有些神秘的细节。

另一种观点

IntPtr是一个有两个限制的指针:

  1. 无法直接取消引用
  2. 它不知道它指向的数据类型。
  3. 换句话说,IntPtr就像void* - 但有额外的功能,它可以(但不应该)用于基本指针算术。

    为了取消引用IntPtr,您可以将其强制转换为真正的指针(只能在“不安全”上下文中执行的操作),或者您可以将其传递给辅助程序,例如提供的那些由InteropServices.Marshal类。使用Marshal类可以提供安全的假象,因为它不需要您处于明确的“不安全”环境中。但是,它不会消除使用指针时固有的崩溃风险。

答案 4 :(得分:13)

什么是指针?

在所有语言中,指针是一种存储内存地址的变量,您可以要求它们告诉您指向的地址或者指向的值。地址他们指着。

指针可以被认为是一种书签。除了用于快速跳转到书中的页面之外,指针用于跟踪或映射内存块。

想象一下你的程序的内存就像一个65535字节的大数组。

指针乖乖地指出

指针每个都记住一个内存地址,因此它们每个都指向内存中的单个地址。

作为一个群体,指针记住并记住内存地址,遵守你的每一个命令和恶心。

你是他们的王。

C#中的指针

  

特别是在C#中,指针是一个整数变量,用于存储0到65534之间的内存地址。

也特定于C#,指针的类型为int,因此签名。

您不能使用带编号的地址,但也不能访问65534以上的地址。任何尝试都会抛出System.AccessViolationException。

一个名为 MyPointer 的指针声明如下:

  

int * MyPointer;

C#中的指针是一个int,但C#中的内存地址从0开始,一直延伸到65534.

应该特别小心处理尖锐的事情

“不安全”一词 旨在吓唬你,并且有一个很好的理由:指针是尖的东西,有点尖锐的东西,例如剑,斧头,指针等应该特别小心处理。

指针给程序员严格控制系统。因此,错误可能会产生更严重的后果。

为了使用指针,必须在程序的属性中启用不安全的代码,并且指针必须专门用于标记为不安全的方法或块中。

不安全区块的示例

unsafe
{
    // Place code carefully and responsibly here.

}

如何使用指针

当声明或实例化变量或对象时,它们存储在内存中。

  • 使用*符号前缀声明指针。

int *MyPointer;

  • 要获取变量的地址,请使用&符号前缀。

MyPointer = &MyVariable;

将地址分配给指针后,以下情况适用:

  • 没有*前缀来指向被指向int的内存地址。

MyPointer = &MyVariable; // Set MyPointer to point at MyVariable

  • 使用*前缀获取存储在指向的内存地址的值。

"MyPointer is pointing at " + *MyPointer;

由于指针是一个保存内存地址的变量,因此该内存地址可以存储在指针变量中。

谨慎负责地使用指针的示例

    public unsafe void PointerTest()
    {
        int x = 100; // Create a variable named x

        int *MyPointer = &x; // Store the address of variable named x into the pointer named MyPointer

        textBox1.Text = ((int)MyPointer).ToString(); // Displays the memory address stored in pointer named MyPointer

        textBox2.Text = (*MyPointer).ToString(); // Displays the value of the variable named x via the pointer named MyPointer.

    }

注意指针的类型是int。这是因为C#将内存地址解释为整数(int)。

为什么是int而不是uint?

没有充分的理由。

为什么要使用指针?

指针非常有趣。由于大部分计算机都由内存控制,指针使程序员能够更好地控制程序的内存。

内存监控。

使用指针读取内存块并监视指向的值如何随时间变化。

负责任地更改这些值,并跟踪更改对计算机的影响。

答案 5 :(得分:7)

MSDN告诉我们:

  

IntPtr类型设计为   大小为的整数   特定于平台的。那是一个   预计这种类型的实例   在32位硬件和32位是32位   操作系统和64位   64位硬件和操作系统。

     

IntPtr类型可以使用   支持指针的语言,和   作为引用数据的常用手段   在做和不做的语言之间   支持指针。

     

IntPtr对象也可用于   握住把手。例如,实例   IntPtr广泛用于   要保存的System.IO.FileStream类   文件句柄。

     

IntPtr类型符合CLS标准,   虽然UIntPtr类型不是。只要   IntPtr类型用于常见的   语言运行时。 UIntPtr类型是   提供主要是为了维护   与IntPtr建筑对称   类型。

http://msdn.microsoft.com/en-us/library/system.intptr(VS.71).aspx

答案 6 :(得分:5)

这是处理IntPtr的{​​{3}}。

第一行是:

  

特定于平台的类型,用于表示指针或句柄。

关于页面进入状态的指针或句柄:

  

IntPtr类型可以使用   支持指针的语言,和   作为引用数据的常用手段   在做和不做的语言之间   支持指针。

     

IntPtr对象也可用于   握住把手。例如,实例   IntPtr广泛用于   要保存的System.IO.FileStream类   文件句柄。

指针是对包含您感兴趣的数据的内存区域的引用。

句柄可以是对象的标识符,当双方都需要访问该对象时,它在方法/类之间传递。

答案 7 :(得分:0)

IntPtrvalue type,主要用于保存内存地址或句柄。 pointer是内存地址。指针可以输入(例如int*)或不输入(例如void*)。 Windows handle是一个通常与内存地址大小相同(或更小)的值,它表示系统资源(如文件或窗口)。