IntPtr 到底是什么?
通过使用 IntelliSense 并查看其他人的代码,我遇到了这种 IntPtr
类型; 每次需要使用它时,我只需放置 null
或 IntPtr.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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(8)
它是一个“本机(特定于平台的)大小整数”。 它在内部表示为
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 useunsafe
code.IntPtr.Zero
is effectivelyNULL
(a null pointer).它是一种足够大的值类型,可以存储本机或不安全代码中使用的内存地址,但不能直接用作安全托管代码中的内存地址。
您可以使用
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.下面是一个示例:
我正在编写一个与高速相机交互的 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.
直接解释
IntPtr 是一个整数,其大小与指针相同。
您可以使用 IntPtr 以非指针类型存储指针值。 此功能在 .NET 中非常重要,因为使用指针非常容易出错,因此在大多数情况下都是非法的。 通过允许将指针值存储在“安全”数据类型中,不安全代码段之间的管道可以用更安全的高级代码来实现,甚至可以用不安全的 .NET 语言来实现。直接支持指针。
IntPtr 的大小是特定于平台的,但很少需要考虑这个细节,因为系统会自动使用正确的大小。
“IntPtr”这个名字很令人困惑——像
Handle
这样的名字可能更合适。 我最初的猜测是“IntPtr”是一个指向整数的指针。 IntPtr 的 MSDN 文档 进入有点神秘的细节,却没有提供太多关于这个名字的含义的见解。另一种观点
IntPtr
是一个有两个限制的指针:换句话说,
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:In other words, an
IntPtr
is just like avoid*
-- 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 theInteropServices.Marshal
class. Using theMarshal
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.什么是指针?
在所有语言中,指针都是一种存储内存地址的变量,您可以要求他们告诉您它们所指向的地址或它们所指向的地址处的值。
指针可以被认为是一种书签。 不过,指针不是用来快速跳转到书中的页面,而是用来跟踪或映射内存块。
将程序的内存想象成一个 65535 字节的大数组。
指针乖乖地指向
指针各自记住一个内存地址,因此它们都指向内存中的一个地址。
作为一个整体,指针会记住并回忆内存地址,并严格遵守您的每一个命令。
你是他们的国王。
C# 中的指针
同样,对于 C# 来说,指针的类型为 int,因此是有符号的。
但是,您不能使用负编号地址,也不能访问 65534 以上的地址。任何这样做的尝试都会抛出 System.AccessViolationException。
一个名为 MyPointer 的指针声明如下:
C# 中的指针是 int,但 C# 中的内存地址从 0 开始,一直延伸到 65534。
处理指针时应格外小心
单词不安全是目的是吓唬你,并且有一个很好的理由:指针是尖头的东西,而尖头的东西,例如剑、斧头、指针等,应该格外小心地处理。
指针使程序员能够严格控制系统。 因此,犯下的错误很可能会带来更严重的后果。
为了使用指针,必须在程序的属性中启用不安全代码,并且必须在标记为不安全的方法或块中专门使用指针。
不安全块的示例
如何使用指针
当声明或实例化变量或对象时,它们将存储在内存中。
int *MyPointer;
MyPointer = &MyVariable;
将地址分配给指针后,将应用以下规则:
MyPointer = &MyVariable; // 设置 MyPointer 指向 MyVariable
"MyPointer is pointing at " + *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#
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:
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
How to use Pointers
When variables or objects are declared or instantiated, they are stored in memory.
int *MyPointer;
MyPointer = &MyVariable;
Once an address is assigned to a pointer, the following applies:
MyPointer = &MyVariable; // Set MyPointer to point at MyVariable
"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
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.
MSDN 告诉我们:
http://msdn.microsoft.com/en- us/library/system.intptr(VS.71).aspx
MSDN tells us:
http://msdn.microsoft.com/en-us/library/system.intptr(VS.71).aspx
嗯,这是 MSDN 页面,它处理与
IntPtr
。第一行写着:
至于指针或句柄是什么,页面继续说明:
指针是对保存您感兴趣的某些数据的内存区域的引用。
句柄可以是对象的标识符,并且当双方都需要访问该对象时在方法/类之间传递。
Well this is the MSDN page that deals with
IntPtr
.The first line reads:
As to what a pointer or handle is the page goes on to state:
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.
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).