Используя IntelliSense и просматривая чужой код, я столкнулся с этим IntPtr
типом; каждый раз, когда это нужно было использовать, я просто помещал null
или IntPtr.Zero
находил большинство функций для работы. Что именно и когда / почему он используется?
171
IntPtr
имеет смысл, потому что это целое число (как в математическом целом) и указатель (как в указателе).Int
Часть имеет мало общего с типом Int - это понятие, а не тип специфичны. Хотя, чтобы быть справедливым, единственное, что спецификация CLI говорит об этом, - это то, что это действительно "Integer, native size". Ну да ладно :)Это тип значения, достаточно большой для хранения адреса памяти, который используется в собственном или небезопасном коде, но его нельзя напрямую использовать в качестве адреса памяти в безопасном управляемом коде.
Вы можете использовать,
IntPtr.Size
чтобы узнать, используете ли вы 32-битный или 64-битный процесс, так как он будет 4 или 8 байтов соответственно.источник
IntPtr
также использовались 32-битные дескрипторы для представления дескрипторов независимо от архитектуры (хотяSize
в этом случае все равно указано 8). В спецификации CLI только отмечается, что это целое число «родного размера», но на самом деле это мало что говорит.Вот пример:
Я пишу программу на C #, которая взаимодействует с высокоскоростной камерой. У камеры есть собственный драйвер, который автоматически получает изображения и загружает их в память компьютера.
Поэтому, когда я готов перенести последнее изображение в мою программу для работы, драйвер камеры предоставляет мне IntPtr для того, где изображение УЖЕ хранится в физической памяти, поэтому мне не нужно тратить время / ресурсы на создание другого блок памяти для хранения изображения, которое уже находится в памяти. IntPtr просто показывает мне, где изображение уже есть.
источник
Прямая интерпретация
IntPtr представляет собой целое число , которое имеет такой же размер , как указатель .
Вы можете использовать IntPtr для хранения значения указателя в типе без указателя. Эта функция важна в .NET, так как использование указателей очень подвержено ошибкам и, следовательно, недопустимо в большинстве случаев. Позволяя сохранить значение указателя в «безопасном» типе данных, прокладка между небезопасными сегментами кода может быть реализована в более безопасном высокоуровневом коде - или даже в языке .NET, который напрямую не поддерживает указатели.
Размер IntPtr зависит от платформы, но эту деталь редко нужно учитывать, поскольку система автоматически использует правильный размер.
Название «IntPtr» сбивает с толку - что-то вроде
Handle
могло бы быть более подходящим. Первоначально я предполагал, что IntPtr - это указатель на целое число. Документации MSDN из IntPtr переходит в несколько скрытом подробно никогда не обеспечивая намного больше информации о значении имени.Альтернативная перспектива
Это
IntPtr
указатель с двумя ограничениями:Другими словами, an
IntPtr
похож на avoid*
- но с дополнительной функцией, которую он может (но не должен) использовать для базовой арифметики указателей.Чтобы разыменовать an
IntPtr
, вы можете либо привести его к истинному указателю (операция, которая может быть выполнена только в «небезопасных» контекстах), либо вы можете передать его вспомогательной подпрограмме, например, предоставляемойInteropServices.Marshal
классом. ИспользованиеMarshal
класса дает иллюзию безопасности, поскольку он не требует от вас явного «небезопасного» контекста. Однако это не устраняет риск сбоя, который присущ указателям.источник
Что такое указатель?
Во всех языках указатель - это тип переменной, в которой хранится адрес памяти, и вы можете либо попросить их сообщить вам адрес, на который они указывают, либо значение по адресу, на который они указывают.
Указатель можно рассматривать как своего рода отметку о книге. За исключением того, что вместо быстрого перехода к странице в книге используется указатель для отслеживания или отображения блоков памяти.
Представьте себе память вашей программы в точности как один большой массив из 65535 байтов.
Указатели послушно указывают
Указатели запоминают один адрес памяти каждый, и поэтому каждый из них указывает на один адрес в памяти.
Как группа, указатели запоминают и запоминают адреса памяти, подчиняясь каждой вашей команде до тошноты.
Вы их король.
Указатели в C #
Также характерные для C #, указатели имеют тип int и поэтому подписаны.
Вы не можете использовать адреса с отрицательной нумерацией, а также не можете получить доступ к адресу выше 65534. Любая попытка сделать это вызовет исключение System.AccessViolationException.
Указатель MyPointer объявлен так:
Указатель в C # - это int, но адреса памяти в C # начинаются с 0 и простираются до 65534.
Остроконечные вещи должны обрабатываться с особой тщательностью
Слово небезопасно это предназначено , чтобы напугать вас, так и для очень веских причин: Указатели заостренных вещи, и заостренных вещи , например , мечи, топоры, указатели и т.д. , должны быть обработан с дополнительной особой тщательности.
Указатели дают программисту жесткий контроль над системой. Поэтому допущенные ошибки могут иметь более серьезные последствия.
Чтобы использовать указатели, небезопасный код должен быть включен в свойствах вашей программы, а указатели должны использоваться исключительно в методах или блоках, помеченных как небезопасные.
Пример небезопасного блока
Как использовать указатели
Когда переменные или объекты объявляются или создаются, они сохраняются в памяти.
int *MyPointer;
MyPointer = &MyVariable;
Как только адрес назначен указателю, применяется следующее:
MyPointer = &MyVariable; // Set MyPointer to point at MyVariable
"MyPointer is pointing at " + *MyPointer;
Поскольку указатель является переменной, которая содержит адрес памяти, этот адрес памяти может быть сохранен в переменной указателя.
Пример использования указателей аккуратно и ответственно
Обратите внимание, что тип указателя - int. Это потому, что C # интерпретирует адреса памяти как целые числа (int).
Почему это int вместо uint?
Нет веской причины.
Зачем использовать указатели?
Указатели очень весело. Так как большая часть компьютера управляется памятью, указатели дают программисту больше контроля над памятью их программ.
Мониторинг памяти.
Используйте указатели для чтения блоков памяти и отслеживания изменения значений, на которые указывают указатели.
Измените эти значения ответственно и следите за тем, как ваши изменения влияют на ваш компьютер.
источник
65534
кажется очень неправильным в качестве указателя диапазона. Вы должны предоставить ссылку.System.IntPtr
. Я хотел бы видеть обновленный ответ в конце, объясняющий, что такжеSystem.IntPtr
и как это относится к небезопасным указателям в C #, пожалуйста.MSDN говорит нам:
http://msdn.microsoft.com/en-us/library/system.intptr(VS.71).aspx
источник
Ну, это страница MSDN, которая имеет дело с
IntPtr
.Первая строка гласит:
Что касается указателя или дескриптора, то страница переходит в состояние:
Указатель - это ссылка на область памяти, которая содержит некоторые данные, которые вас интересуют.
Дескриптор может быть идентификатором объекта и передается между методами / классами, когда обеим сторонам необходим доступ к этому объекту.
источник
An
IntPtr
является типом значения, который в основном используется для хранения адресов или дескрипторов памяти. Указатель является адресом памяти. Указатель может быть напечатан (напримерint*
) или нетипизирован (напримерvoid*
). Дескриптор Windows - это значение, которое обычно имеет тот же размер (или меньше), что и адрес памяти, и представляет системный ресурс (например, файл или окно).источник