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?
相关问题
- Sorting 3 numbers without branching [closed]
- Graphics.DrawImage() - Throws out of memory except
- Why am I getting UnauthorizedAccessException on th
- 求获取指定qq 资料的方法
- How to know full paths to DLL's from .csproj f
MSDN tells us:
http://msdn.microsoft.com/en-us/library/system.intptr(VS.71).aspx
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.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 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.
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.
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).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.