Что такое IntPtr?
используя IntelliSense и глядя на код других людей, я столкнулся с этим IntPtr
тип; каждый раз, когда его нужно было использовать, я просто поставил null
или IntPtr.Zero
и нашел большинство функций для работы. Что это такое и когда / почему оно используется?
7 ответов
это " собственное (специфичное для платформы) целое число размера."Это внутренне представлено как void*
но представляется как целое число. Вы можете использовать его, когда вам нужно сохранить неуправляемый указатель и не хотите использовать unsafe
код. IntPtr.Zero
эффективно NULL
(нулевой указатель).
Это тип значения, достаточно большой для хранения адреса памяти, используемого в собственном или небезопасном коде, но не используемый напрямую в качестве адреса памяти в безопасном управляемом коде.
можно использовать IntPtr.Size
чтобы узнать, работаете ли вы в 32-битном или 64-битном процессе, так как это будет 4 или 8 байт соответственно.
вот пример:
Я пишу программу на C#, которая взаимодействует с высокоскоростной камеры. Камера имеет свой собственный драйвер, который получает изображения и загружает их в память компьютера автоматически.
поэтому, когда я готов принести последнее изображение в мою программу для работы, драйвер камеры предоставляет мне IntPtr, где изображение уже хранится в физической памяти, поэтому мне не нужно тратить время / ресурсы на создание другого блока памяти для храните образ, который уже есть в памяти. IntPtr просто показывает мне, где изображение уже есть.
прямой перевод
An IntPtr это целое который имеет тот же размер, что и указатель.
вы можете использовать IntPtr для хранения значения указателя в типе без указателя. Эта функция важна в .NET, так как использование указателей очень подвержено ошибкам и поэтому незаконно в большинстве контекстов. Позволяя значение указателя храниться в" безопасном " типе данных, сантехника между небезопасных сегменты кода могут быть реализован в более безопасном коде высокого уровня - или даже на языке .NET, который напрямую не поддерживает указатели.
размер IntPtr зависит от платформы, но эту деталь редко нужно учитывать, так как система автоматически будет использовать правильный размер.
название "IntPtr" сбивает с толку - что-то вроде Handle
было бы более уместно. Мое первоначальное предположение состояло в том, что" IntPtr " был указателем to целое число. The документация MSDN указателя IntPtr переходит в несколько загадочные детали, никогда не давая много понимания о значении имени.
альтернативную точку зрения
An IntPtr
указатель с двумя ограничениями:
- он не может быть напрямую разыменован
- он не знает тип данных, которые он указывает.
другими словами, an IntPtr
как void*
-- но с дополнительной функцией, которая он может (но не должен) использоваться для базовой арифметики указателя.
для того, чтобы разыменовать элемент IntPtr
, вы можете либо привести его к истинному указателю (операция, которая может быть выполнена только в "небезопасных" контекстах), либо передать его вспомогательной процедуре, такой как те, которые предоставляются InteropServices.Marshal
класса. С помощью Marshal
класс дает иллюзию безопасности, поскольку он не требует, чтобы Вы были в явном "небезопасном" контексте. Тем не менее, это не устраняет риск сбоя, который присущ использование указателей.
что такое указатель?
на всех языках, указатель-это тип переменной, которая хранит адрес в памяти, и вы можете либо попросите их сказать вам адрес они указывают на или значение по адресу они указывают на.
указатель можно рассматривать как своего рода книжный знак. За исключением того, что вместо быстрого перехода на страницу в книге указатель используется для отслеживания или отображения блоков память.
представьте память вашей программы точно как один большой массив 65535 байт.
указатели указывают послушно
указатели запоминают по одному адресу памяти, и поэтому каждый из них указывает на один адрес в памяти.
как группа, указатели запоминают и запоминают адреса памяти, подчиняясь каждой вашей команде до тошноты.
ты их король.
указатели в В C#
в частности, в C# указатель представляет собой целочисленную переменную, которая хранит адрес памяти между 0 и 65534.
также специфично для C#, указатели имеют тип int и, следовательно, подписаны.
вы не можете использовать отрицательно пронумерованные адреса, хотя и не можете получить доступ к адресу выше 65534. Любая попытка сделать это приведет к сбою системы.Как AccessViolationException.
указатель под названием MyPointer объявляется как Итак:
int *MyPointer;
указатель в C# является int, но адреса памяти в C# начинаются с 0 и простираются до 65534.
заостренные вещи должны обрабатываться с особой осторожностью
слово небезопасных is предназначен для того, чтобы напугать вас, и по очень веской причине: указатели-это острые вещи, и острые вещи, например, мечи, топоры, указатели и т. д. следует относиться с особенным уход.
указатели дают программисту жесткий контроль над системой. Поэтому ошибки могут иметь более серьезные последствия.
чтобы использовать указатели, небезопасный код должен быть включен в свойствах вашей программы, а указатели должны использоваться исключительно в методах или блоках, помеченных как небезопасные.
пример небезопасного блока
unsafe
{
// Place code carefully and responsibly here.
}
как использовать указатели
когда переменные или объекты объявляются или создаются экземпляры, они хранятся в памяти.
- объявите указатель с помощью префикса * symbol.
int *MyPointer;
- для получения адреса переменной используется префикс & symbol.
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. Это потому, что C# интерпретирует адреса памяти как целые числа (int).
почему это int вместо uint?
нет оснований.
зачем использовать указатели?
указатели очень весело. Поскольку большая часть компьютера контролируется памятью, указатели дают программисту больше возможностей контролировать память своей программы.
Контроль памяти.
использовать указатели для чтения блоков памяти и контролируйте, как значения, на которые указывают, меняются с течением времени.
измените эти значения ответственно и следите за тем, как ваши изменения влияют на ваш компьютер.
MSDN сообщает нам:
тип IntPtr конструирован для того чтобы быть целое число, размер которого платформы. То есть ожидается, что экземпляр этого типа быть 32-бит на 32-битном оборудовании и операционные системы и 64-разрядные 64-разрядное оборудование и операционные системы.
тип IntPtr может использоваться языки, поддерживающие указатели, и в качестве общего средства ссылки на данные между языками, которые делают и не делают поддержка указателей.
объекты IntPtr также могут использоваться для держите ручки. Например, экземпляры IntPtr использованы обширно в Система.ИО.Класс FileStream для хранения дескриптор файла.
тип IntPtr CLS-совместимый, в то время как тип UIntPtr не является. Только тип IntPtr используется в общем среда CLR. Тип UIntPtr является в основном для поддержания архитектурная симметрия с IntPtr тип.
http://msdn.microsoft.com/en-us/library/system.intptr (VS.71).aspx
Ну это страница MSDN что касается IntPtr
.
первая строка гласит:
специфичный для платформы тип, используемый для представления указателя или дескриптора.
как указатель или дескриптор страницы гласит:
тип IntPtr может использоваться языки, поддерживающие указатели, и в качестве общего средства ссылки на данные между языками, которые делают и не делают поддержка указатели.
объекты IntPtr также могут использоваться для держите ручки. Например, экземпляры IntPtr использованы обширно в Система.ИО.Класс FileStream для хранения дескриптор файла.
указатель-это ссылка на область памяти, которая содержит некоторые данные, которые вас интересуют.
дескриптор может быть идентификатором объекта и передается между методов/классов, когда обе стороны должны получить доступ к этому объекту.