tags:

views:

911

answers:

6

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?

+2  A: 

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.

ChrisF
Not really. What is a pointer/handle? I know that function pointers in C++ changed into delegates in C#, but that is the limit of my knowledge.
Callum Rogers
+12  A: 

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

280Z28
Again, what is a pointer?
Callum Rogers
A pointer is something that points to an address in memory. In managed languages you have references (the address can move around) while in unmanaged languages you have pointers (the address is fixed)
Colin Mackay
In general (across programming languages), a pointer is a number that represents a physical location in memory. A *null* pointer is (almost always) one that points to 0, and is widely recognized as "not pointing to anything". Since systems have different amounts of supported memory, it doesn't always take the same number of bytes to hold that number, so we call a "native size integer" one that can hold a pointer on any particular system.
280Z28
+6  A: 

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.

Daniel Earwicker
Good point about detecting the size of address space for the process.
Noldorin
+3  A: 

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

Zyphrax
+3  A: 

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.

bufferz
So the IntPtr simple allows you to use an unmanaged pointer (like that used in your camera driver) in managed code?
Callum Rogers
Yes. Well in this case, most likely the camera driver uses unmanaged drivers under the hood, but in order to operate properly in the Managed-only world it provides the IntPtr to allow me to work with the data safely.
bufferz
+1  A: 

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.

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

In my opinion, the name "IntPtr" is confusing. My initial guess was that "IntPtr" was a pointer to an integer. The MSDN documentation of IntPtr goes into somewhat cryptic detail without ever giving a clear explanation of the name.

nobar
There is some precedent for the name "intptr" from the C99 standard of the "C" programming language. http://linux.die.net/man/3/intptr_t.
nobar
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 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.
nobar