Используя IntelliSense и глядя на код других людей, я столкнулся с этим типом IntPtr
; каждый раз, когда это нужно было использовать, я просто положил null
или IntPtr.Zero
и нашел большинство функций для работы. Что именно это и когда/почему оно используется?
Просто что такое IntPtr?
Ответ 1
Это "родной (определенный платформой) размер целого числа". Он внутренне представлен как void*
, но отображается как целое число. Вы можете использовать его всякий раз, когда вам нужно сохранить неуправляемый указатель и не хотите использовать код unsafe
. IntPtr.Zero
эффективно NULL
(нулевой указатель).
Ответ 2
Это тип значения, достаточно большой для хранения адреса памяти, используемого в собственном или небезопасном коде, но не используемого непосредственно в качестве адреса памяти в безопасном управляемом коде.
Вы можете использовать IntPtr.Size
, чтобы узнать, работаете ли вы в 32-разрядном или 64-битном процессе, так как это будет 4 или 8 байтов соответственно.
Ответ 3
Вот пример:
Я пишу программу на С#, которая взаимодействует с высокоскоростной камерой. У камеры есть свой собственный драйвер, который приобретает изображения и автоматически загружает их в память компьютера.
Итак, когда я готов принести последнее изображение в свою программу для работы, драйвер камеры предоставит мне IntPtr, где изображение будет УЖЕ сохранено в физической памяти, поэтому мне не нужно тратить время/ресурсы создают еще один блок памяти для хранения изображения, которое уже в памяти. IntPtr просто показывает мне, где изображение уже есть.
Ответ 4
Прямая интерпретация
IntPtr - это целое число того же размера, что и указатель.
Вы можете использовать IntPtr для хранения значения указателя в типе без указателя. Эта функция важна в .NET, так как использование указателей очень подвержено ошибкам и поэтому в большинстве случаев недопустимо. Позволяя сохранить значение указателя в "безопасном" типе данных, прокладка между небезопасными сегментами кода может быть реализована в более безопасном высокоуровневом коде - или даже в языке .NET, который напрямую не поддерживает указатели.
Размер IntPtr зависит от платформы, но эту деталь редко нужно учитывать, поскольку система автоматически использует правильный размер.
Название "IntPtr" сбивает с толку - что-то вроде Handle
могло бы быть более подходящим. Первоначально я предполагал, что IntPtr - это указатель на целое число. Документация по MSDN для IntPtr углубляется в некоторые загадочные подробности, не давая много информации о значении имени.
Альтернативная перспектива
IntPtr
- это указатель с двумя ограничениями:
- Это не может быть напрямую разыменовано
- Он не знает тип данных, на которые он указывает.
Другими словами, IntPtr
похож на void*
- но с дополнительной функцией, которую он может (но не должен) использовать для базовой арифметики указателей.
Чтобы разыменовать IntPtr
, вы можете либо привести его к истинному указателю (операция, которая может быть выполнена только в "небезопасных" контекстах), либо передать его вспомогательной подпрограмме, например, предоставляемой классом InteropServices.Marshal
. Использование класса Marshal
дает иллюзию безопасности, поскольку не требует, чтобы вы находились в явном "небезопасном" контексте. Тем не менее, это не устраняет риск сбоя, который присущ указателям.
Ответ 5
Что такое указатель?
Во всех языках указатель представляет собой тип переменной, в которой хранится адрес памяти, и вы можете попросить их указать адрес, на который они указывают, или значение на адрес, на которые они указывают.
Указатель можно рассматривать как своего рода книжный знак. Кроме того, вместо того, чтобы быстро перейти к странице в книге, указатель используется для отслеживания или отображения блоков памяти.
Представьте свою память программ точно как один большой массив из 65535 байт.
Указатели указывают послушно
Указатели запоминают один адрес памяти каждый, и поэтому каждый указывает на один адрес в памяти.
В качестве группы указатели запоминают и запоминают адреса памяти, подчиняясь каждой вашей рекламной паузе.
Ты их король.
Указатели в С#
В частности, в С# указатель представляет собой целочисленную переменную, которая хранит адрес памяти от 0 до 65534.
Также, для С#, указатели имеют тип int и поэтому подписываются.
Вы не можете использовать отрицательно пронумерованные адреса, хотя вы также не можете получить доступ к адресу выше 65534. Любая попытка сделать это вызовет исключение System.AccessViolationException.
Указатель, называемый MyPointer, объявляется следующим образом:
int * MyPointer;
Указатель в С# - это int, но адреса памяти в С# начинаются с 0 и расширяются до 65534.
Пояснительные вещи следует обрабатывать с особой осторожностью
Слово небезопасное предназначено для того, чтобы напугать вас, и по очень веской причине: Указатели - это заостренные вещи и заостренные вещи, например. мечи, оси, указатели и т.д. следует обрабатывать с особой осторожностью.
Указатели дают программисту жесткий контроль над системой. Поэтому сделанные ошибки могут иметь более серьезные последствия.
Чтобы использовать указатели, в ваших программных свойствах должен быть включен небезопасный код, а указатели должны использоваться исключительно в методах или блоках, помеченных как небезопасные.
Пример небезопасного блока
unsafe
{
// Place code carefully and responsibly here.
}
Как использовать указатели
Когда переменные или объекты объявляются или создаются, они сохраняются в памяти.
- Объявить указатель, используя префикс *.
int *MyPointer;
- Чтобы получить адрес переменной, вы используете префикс и символ.
MyPointer = &MyVariable;
Как только адрес присваивается указателю, применяется следующее:
- Без * префикса ссылаться на адрес памяти, на который указывает int.
MyPointer = &MyVariable; // Set MyPointer to point at 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. Это связано с тем, что С# интерпретирует адреса памяти как целые числа (int).
Почему это int вместо uint?
Нет веской причины.
Зачем использовать указатели?
Указатели очень забавны. Поскольку большая часть компьютера управляется памятью, указатели предоставляют программисту больше контроля над их программной памятью.
Мониторинг памяти.
Используйте указатели для чтения блоков памяти и отслеживайте, как значения, указывающие на изменение во времени.
Измените эти значения ответственно и отслеживайте, как ваши изменения влияют на ваш компьютер.
Ответ 6
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
Ответ 7
Ну, это страница MSDN, которая имеет дело с IntPtr
.
Первая строка гласит:
Специфичный для платформы тип, который используется для представления указателя или дескриптора.
Что касается указателя или дескриптора, то страница переходит в состояние:
Тип IntPtr может использоваться языками, которые поддерживают указатели, и в качестве общего средства обращения к данным между языками, которые поддерживают и не поддерживают указатели.
Объекты IntPtr также можно использовать для хранения дескрипторов. Например, экземпляры IntPtr широко используются в классе System.IO.FileStream для хранения файловых дескрипторов.
Указатель - это ссылка на область памяти, в которой хранятся некоторые данные, которые вас интересуют.
Дескриптор может быть идентификатором объекта и передается между методами/классами, когда обеим сторонам необходим доступ к этому объекту.
Ответ 8
IntPtr
- это тип значения, который в основном используется для хранения адресов или дескрипторов памяти. Указатель является адресом памяти. Указатель может быть напечатан (например, int*
) или нетипизирован (например, void*
). Дескриптор Windows - это значение, которое обычно имеет тот же размер (или меньше), что и адрес памяти, и представляет системный ресурс (например, файл или окно).