Я смотрел декларацию P/Invoke RegOpenKeyEx
, когда заметил этот комментарий на странице:
Изменен
IntPtr
наUIntPtr
: при вызовеIntPtr
для дескрипторов вы перейдете в переполнение.UIntPtr
- правильный выбор, если вы хотите, чтобы это правильно работало на 32- и 64-разрядных платформах.
Это не имеет большого значения для меня: оба IntPtr
и UIntPtr
должны представлять указатели, поэтому их размер должен соответствовать битности ОС - либо 32 бита, либо 64 бита. Поскольку это не цифры, а указатели, их числовые значения, указанные в них, не должны иметь значения, а только биты, представляющие адрес, на который они указывают. Я не могу придумать какой-либо причины, по которой была бы разница между этими двумя, но этот комментарий сделал меня неопределенным.
Есть ли конкретная причина использовать UIntPtr
вместо IntPtr
? В соответствии с документация:
Тип
IntPtr
CLS-совместимый, а типUIntPtr
- нет. В режиме общего языка используется только типIntPtr
. ТипUIntPtr
предоставляется в основном для сохранения архитектурной симметрии с типомIntPtr
.
Это, конечно, подразумевает, что нет никакой разницы (если кто-то не пытается преобразовать значения в целые числа). Так неверно ли приведенный комментарий от pinvoke.net?
Edit
После прочтения ответа MarkH я немного проверял и выяснил, что приложения .NET не имеют большого адреса и могут обрабатывать только 2GB виртуальные адресное пространство при компиляции в 32-битном режиме. (Можно использовать взломать, чтобы включить флаг большого адреса, но ответ MarkH показывает, что проверки внутри .NET Framework будут ломать вещи, потому что предполагается, что адресное пространство только 2 ГБ, а не 3 ГБ.)
Это означает, что все правильные адреса виртуальной памяти, которые может иметь указатель (насколько это касается .NET Framework), будут находиться между 0x00000000 и 0x7FFFFFFF. Когда этот диапазон будет переведен на подписанный int
, никакие значения не будут отрицательными, потому что старший бит не установлен. Это подтверждает мое убеждение, что нет никакой разницы в использовании IntPtr vs UIntPtr. Правильно ли мои рассуждения?
Fermat2357 указал, что указанное выше изменение неверно.