C# 究竟什么是 IntPtr?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1148177/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-06 09:23:33  来源:igfitidea点击:

Just what is an IntPtr exactly?

c#intptr

提问by Callum Rogers

Through using IntelliSense and looking at other people's code, I have come across this IntPtrtype; every time it has needed to be used I have simply put nullor IntPtr.Zeroand found most functions to work. What exactly is it and when/why is it used?

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

采纳答案by Sam Harwell

It's a "native (platform-specific) size integer." It's internally represented as void*but exposed as an integer. You can use it whenever you need to store an unmanaged pointer and don't want to use unsafecode. IntPtr.Zerois effectively NULL(a null pointer).

它是一个“本机(特定于平台)大小的整数”。它在内部表示为void*但公开为整数。您可以在需要存储非托管指针且不想使用unsafe代码时使用它。IntPtr.Zero是有效的NULL(空指针)。

回答by ChrisF

Well this is the MSDN pagethat deals with IntPtr.

嗯,这是MSDN页面是涉及IntPtr

The first line reads:

第一行写着:

A platform-specific type that is used to represent a pointer or a handle.

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

As to what a pointer or handle is the page goes on to state:

至于什么是指针或句柄,页面继续说明:

The IntPtr type can be used by languages that support pointers, and as a common means of referring to data between languages that do and do not support pointers.

IntPtr objects can also be used to hold handles. For example, instances of IntPtr are used extensively in the System.IO.FileStream class to hold file handles.

IntPtr 类型可由支持指针的语言使用,并作为在支持和不支持指针的语言之间引用数据的常用方法。

IntPtr 对象也可用于保存句柄。例如,在 System.IO.FileStream 类中广泛使用 IntPtr 的实例来保存文件句柄。

A pointer is a reference to an area of memory that holds some data you are interested in.

指针是对保存您感兴趣的一些数据的内存区域的引用。

A handle can be an identifier for an object and is passed between methods/classes when both sides need to access that object.

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

回答by Daniel Earwicker

It's a value type large enough to store a memory address as used in native or unsafe code, but not directly usable as a memory address in safe managed code.

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

You can use IntPtr.Sizeto find out whether you're running in a 32-bit or 64-bit process, as it will be 4 or 8 bytes respectively.

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

回答by Zyphrax

MSDN tells us:

MSDN 告诉我们:

The IntPtr type is designed to be an integer whose size is platform-specific. That is, an instance of this type is expected to be 32-bits on 32-bit hardware and operating systems, and 64-bits on 64-bit hardware and operating systems.

The IntPtr type can be used by languages that support pointers, and as a common means of referring to data between languages that do and do not support pointers.

IntPtr objects can also be used to hold handles. For example, instances of IntPtr are used extensively in the System.IO.FileStream class to hold file handles.

The IntPtr type is CLS-compliant, while the UIntPtr type is not. Only the IntPtr type is used in the common language runtime. The UIntPtr type is provided mostly to maintain architectural symmetry with the IntPtr type.

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

IntPtr 类型可由支持指针的语言使用,并作为在支持和不支持指针的语言之间引用数据的常用方法。

IntPtr 对象也可用于保存句柄。例如,在 System.IO.FileStream 类中广泛使用 IntPtr 的实例来保存文件句柄。

IntPtr 类型符合 CLS,而 UIntPtr 类型不符合。公共语言运行库中仅使用 IntPtr 类型。提供 UIntPtr 类型主要是为了保持与 IntPtr 类型的架构对称性。

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

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

回答by bufferz

Here's an example:

下面是一个例子:

I'm writing a C# program that interfaces with a high speed camera. The camera has its own driver that acquires images and loads them into the computer's memory for me automatically.

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

So when I'm ready to bring the latest image into my program to work with, the camera driver provides me with an IntPtr to where to image is ALREADY stored in physical memory, so I don't have to waste time/resources creating another block of memory to store an image that's in memory already. The IntPtr just shows me where the image already is.

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

回答by nobar

A direct interpretation

直接解释

An IntPtris an integerwhich is the same size as a pointer.

一个IntPtr的是一个整数,其是大小相同的指针

You can use IntPtr to store a pointer value in a non-pointer type. This feature is important in .NET since using pointers is highly error prone and therefore illegal in most contexts. By allowing the pointer value to be stored in a "safe" data type, plumbing between unsafecode segments may be implemented in safer high-level code -- or even in a .NET language that doesn't directly support pointers.

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

The size of IntPtr is platform-specific, but this detail rarely needs to be considered, since the system will automatically use the correct size.

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

The name "IntPtr" is confusing -- something like Handlemight have been more appropriate. My initial guess was that "IntPtr" was a pointer toan integer. The MSDN documentation of IntPtrgoes into somewhat cryptic detail without ever providing much insight about the meaning of the name.

“IntPtr”这个名字令人困惑——像这样的东西Handle可能更合适。我最初的猜测是,“IntPtr的”是一个指针一个整数。IntPtrMSDN 文档进入了一些神秘的细节,但从未提供有关名称含义的太多见解。

An alternative perspective

另一种观点

An IntPtris a pointer with two limitations:

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

  1. It cannot be directly dereferenced
  2. It doesn't know the type of the data that it points to.
  1. 不能直接解引用
  2. 它不知道它指向的数据类型。

In other words, an IntPtris just like a void*-- but with the extra feature that it can (but shouldn't) be used for basic pointer arithmetic.

换句话说, anIntPtr就像 a void*-- 但有一个额外的特性,它可以(但不应该)用于基本的指针算术。

In order to dereference an IntPtr, you can either cast it to a true pointer (an operation which can only be performed in "unsafe" contexts) or you can pass it to a helper routine such as those provided by the InteropServices.Marshalclass. Using the Marshalclass gives the illusion of safety since it doesn't require you to be in an explicit "unsafe" context. However, it doesn't remove the risk of crashing which is inherent in using pointers.

为了取消引用 an IntPtr,您可以将其强制转换为真正的指针(只能在“不安全”上下文中执行的操作),也可以将其传递给诸如InteropServices.Marshal类提供的帮助程序。使用Marshal该类会产生安全的错觉,因为它不需要您处于明确的“不安全”上下文中。但是,它并没有消除使用指针固有的崩溃风险。

回答by WonderWorker

What is a Pointer?

什么是指针?

In all languages, a pointer is a type of variable that stores a memory address, and you can either ask them to tell you the addressthey are pointing at or the value at the addressthey are pointing at.

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

A pointer can be thought of as a sort-of book mark. Except, instead of being used to jump quickly to a page in a book, a pointer is used to keep track of or map blocks of memory.

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

Imagine your program's memory precisely like one big array of 65535 bytes.

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

Pointers point obediently

乖乖的指指点点

Pointers remember one memory address each, and therefore they each point to a single address in memory.

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

As a group, pointers remember and recall memory addresses, obeying your every command ad nauseum.

作为一个组,指针记住并调用内存地址,服从你的每一个命令。

You are their king.

你是他们的国王。

Pointers in C#

C#中的指针

Specifically in C#, a pointer is an integer variable that stores a memory address between 0 and 65534.

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

Also specific to C#, pointers are of type int and therefore signed.

同样特定于 C#,指针是 int 类型,因此是有符号的。

You can't use negatively numbered addresses though, neither can you access an address above 65534. Any attempt to do so will throw a System.AccessViolationException.

但是,您不能使用负编号地址,也不能访问高于 65534 的地址。任何尝试这样做都会引发 System.AccessViolationException。

A pointer called MyPointeris declared like so:

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

int *MyPointer;

int *我的指针;

A pointer in C# is an int, but memory addresses in C# begin at 0 and extend as far as 65534.

C# 中的指针是 int,但 C# 中的内存地址从 0 开始并扩展到 65534。

Pointy things should be handled with extra special care

尖锐的东西应该特别小心处理

The word unsafe isintended to scare you, and for a very good reason: Pointers are pointy things, and pointy things e.g. swords, axes, pointers, etc. should be handled with extra special care.

不安全这个词为了吓唬你,有一个很好的理由:指针是尖尖的东西,尖尖的东西,如剑、斧头、指针等,应该特别小心处理。

Pointers give the programmer tight control of a system. Therefore mistakes made are likely to have more serious consequences.

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

In order to use pointers, unsafe code has to be enabled in your program's properties, and pointers have to be used exclusively in methods or blocks marked as unsafe.

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

Example of an unsafe block

不安全块的示例

unsafe
{
    // Place code carefully and responsibly here.

}

How to use Pointers

如何使用指针

When variables or objects are declared or instantiated, they are stored in memory.

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

  • Declare a pointer by using the * symbol prefix.
  • 使用 * 符号前缀声明一个指针。

int *MyPointer;

int *MyPointer;

  • To get the address of a variable, you use the & symbol prefix.
  • 要获取变量的地址,请使用 & 符号前缀。

MyPointer = &MyVariable;

MyPointer = &MyVariable;

Once an address is assigned to a pointer, the following applies:

将地址分配给指针后,以下内容适用:

  • Without * prefix to refer to the memory address being pointed to as an int.
  • 没有 * 前缀来引用被指向为 int 的内存地址。

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

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

  • With * prefix to get the value stored at the memory address being pointed to.
  • 使用 * 前缀来获取存储在所指向的内存地址处的值。

"MyPointer is pointing at " + *MyPointer;

"MyPointer is pointing at " + *MyPointer;

Since a pointer is a variable that holds a memory address, this memory address can be stored in a pointer variable.

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

Example of pointers being used carefully and responsibly

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

    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.

    }

Notice the type of the pointer is an int. This is because C# interprets memory addresses as integer numbers (int).

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

Why is it int instead of uint?

为什么是 int 而不是 uint?

There is no good reason.

没有充分的理由。

Why use pointers?

为什么要使用指针?

Pointers are a lot of fun. With so much of the computer being controlled by memory, pointers empower a programmer with more control of their program's memory.

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

Memory monitoring.

内存监控。

Use pointers to read blocks of memory and monitor how the values being pointed at change over time.

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

Change these values responsibly and keep track of how your changes affect your computer.

负责任地更改这些值并跟踪您的更改如何影响您的计算机。

回答by cdiggins

An IntPtris a value typethat is primarily used to hold memory addresses or handles. A pointeris a memory address. A pointer can be typed (e.g. int*) or untyped (e.g. void*). A Windows handleis a value that is usually the same size (or smaller) than a memory address and represents a system resource (like a file or window).

AnIntPtr是一种值类型,主要用于保存内存地址或句柄。甲指针是一个存储器地址。指针可以是有类型的(例如int*)或无类型的(例如void*)。甲视窗手柄是通常具有相同的尺寸(或小于)的存储器地址和表示系统资源(如文件或窗口)的值。