Подтвердить что ты не робот

Int vs IntPtr, когда у вас есть ручка?

Сначала возникает вопрос:

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

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

  • IntPtr: Control.Handle
  • 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 vs IntPtr? Это важно для ручек? Вы можете использовать либо?

4b9b3361

Ответ 1

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

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

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

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

Update:

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

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

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

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