INT против IntPtr, когда у вас есть дескриптор? - PullRequest
13 голосов
/ 30 ноября 2010

Первый фоновый вопрос:

В общем, в чем разница между int и IntPtr? Я предполагаю, что это фактический объект, а не значение типа int или byte. Предполагая, что это правда:

Так что они не одинаковы. Все же я вижу ручки, представленные как оба.

  1. IntPtr: Control.Handle
  2. int (или uint): PInvoke можно настроить так, чтобы он возвращал int, и он прекрасно работает:

    [DllImport("coredll.dll", SetLastError = true)]
    public static extern int GetForegroundWindow();
    private string GetActiveWindow()
    {
        const int nChars = 256;
        int handle = 0;
        StringBuilder Buff = new StringBuilder(nChars);
    
        handle = CoreDLL.GetForegroundWindow();
    
        if (CoreDLL.GetWindowText(handle, Buff, nChars) > 0)
        {
            return Buff.ToString();
        }
    
        return "";
    }
    

Итак, int против IntPtr? Имеет ли это значение для ручек? Вы можете использовать либо?

1 Ответ

30 голосов
/ 30 ноября 2010

int имеет длину 32 бита. IntPtr столько же, сколько указатель для вашей архитектуры. Следовательно, указатель может быть сохранен в int только в 32-битных системах, в то время как он может всегда храниться в IntPtr.

Обратите внимание, что ваш пример "int as return value" не использует int для хранения указателя, а только для хранения числового значения. Это не означает, что int автоматически соответствует правильному размеру: автор этой подписи P / Invoke должен был обратиться к документации для GetForegroundWindow и увидеть, что он возвращает HWND.

Затем из windef.h в SDK платформы (или на этой странице MSDN ) мы можем видеть, что HWND - это HANDLE, то есть PVOID, который ... a указатель!

Поэтому, насколько я могу судить, эта подпись неверна , так как размер возвращаемого значения GetForegroundWindow зависит от архитектуры. Таким образом, это также должно быть IntPtr.

Обновление:

Хотя это можно сделать из вышесказанного, я думаю, стоит прямо указать, что:

  • Ошибочное использование int вместо IntPtr в 32-битных приложениях никогда не вызовет проблем, даже если они работают на 64-битной Windows; так как большинство приложений на данный момент 32-битные, это позволит вам часто избегать таких ошибок.
  • Ошибочное использование int вместо IntPtr в 64-битных приложениях не гарантирует , что может вызвать проблемы, поскольку на практике вполне возможно, что встречающиеся значения будут соответствовать 32 битам int. Это дополнительно уменьшает вероятность того, что ошибка проявится как ошибка приложения.

Таким образом, для фактической ошибки существует три условия, которые должны быть выполнены одновременно:

  1. int используется там, где должно быть IntPtr.
  2. Исполняемый образ является 64-разрядным.
  3. Значение, возвращаемое некоторым вызовом PInvoke и сохраняемое как int, на самом деле превышает 32 бита.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...