IntPtr 到底是什么?

发布于 2024-07-27 04:12:56 字数 161 浏览 5 评论 0原文

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

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(8

水溶 2024-08-03 04:12:56

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

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 unsafe code. IntPtr.Zero is effectively NULL (a null pointer).

吃兔兔 2024-08-03 04:12:56

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

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

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.Size to find out whether you're running in a 32-bit or 64-bit process, as it will be 4 or 8 bytes respectively.

不必你懂 2024-08-03 04:12:56

下面是一个示例:

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

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

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.

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 the 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.

梦里人 2024-08-03 04:12:56

直接解释

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

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

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

“IntPtr”这个名字很令人困惑——像Handle这样的名字可能更合适。 我最初的猜测是“IntPtr”是一个指向整数的指针。 IntPtr 的 MSDN 文档 进入有点神秘的细节,却没有提供太多关于这个名字的含义的见解。

另一种观点

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

  1. 它不能直接取消引用
  2. 它不知道它指向的数据的类型。

换句话说, IntPtr 就像 void* - 但具有额外的功能,它可以(但不应该)用于基本的指针算术。

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

A direct interpretation

An IntPtr is an integer which is the same size as a pointer.

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 unsafe code segments may be implemented in safer high-level code -- or even in a .NET language that doesn't directly support pointers.

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

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

An alternative perspective

An IntPtr is a pointer with two limitations:

  1. It cannot be directly dereferenced
  2. It doesn't know the type of the data that it points to.

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

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.Marshal class. Using the Marshal class 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.

心作怪 2024-08-03 04:12:56

什么是指针?

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

指针可以被认为是一种书签。 不过,指针不是用来快速跳转到书中的页面,而是用来跟踪或映射内存块。

将程序的内存想象成一个 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; // 设置 MyPointer 指向 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?

没有充分的理由。

为什么使用指针?

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

内存监控。

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

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

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 address they are pointing at or the value at the address they 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.

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#

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

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

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.

A pointer called MyPointer is declared like so:

int *MyPointer;

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

Pointy things should be handled with extra special care

The word unsafe is intended 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;

  • To get the address of a variable, you use the & symbol prefix.

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.

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;

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).

Why is it int instead of 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.

薄荷→糖丶微凉 2024-08-03 04:12:56

MSDN 告诉我们:

IntPtr 类型被设计为
大小为的整数
特定于平台的。 也就是说,一个
这种类型的实例预计
在 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

MSDN tells us:

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.

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

永言不败 2024-08-03 04:12:56

嗯,这是 MSDN 页面,它处理与IntPtr

第一行写着:

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

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

IntPtr 类型可用于
支持指针的语言,以及
作为引用数据的常用方式
存在和不存在的语言之间
支持指针。

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

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

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

Well this is the MSDN page that deals with 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.

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.

何处潇湘 2024-08-03 04:12:56

IntPtr 是一个 值type 主要用于保存内存地址或句柄。 指针是一个内存地址。 指针可以是类型化的(例如int*)或非类型化的(例如void*)。 Windows 句柄 是一个通常与内存地址并代表系统资源(如文件或窗口)。

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

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文