Как конвертировать IntPtr в int

дескриптор окна, иногда типа int и другие времена типа IntPtr

int пример:

 [DllImport("user32.dll")]
    static extern uint GetWindowThreadProcessId(int hWnd, int ProcessId);    

IntPtr пример:

  [DllImport("user32.dll", CharSet = CharSet.Auto)]
    static extern IntPtr SendMessage(IntPtr hWnd, uint Msg, int wParam, StringBuilder lParam);

я, похоже, не могу конвертировать/бросать из одного в другой.

когда я пытаюсь this.ProcessID = GetWindowThreadProcessId(windowHandle.ToInt32(),0) Я получаю сообщение об ошибке cannot implicitly convert from uint to int

3 ответов


на SendMessage подпись

static extern IntPtr SendMessage(IntPtr hWnd, UInt32 Msg, IntPtr wParam, IntPtr lParam);

или это

static extern IntPtr SendMessage(IntPtr hWnd, UInt32 Msg, IntPtr wParam, StringBuilder lParam);

не обмен int и IntPtr. Они почти эквивалентны только при 32 битах (равных по размеру). На 64 битах IntPtr почти эквивалентно long (равные по размеру)

на GetWindowThreadProcessId подпись

static extern uint GetWindowThreadProcessId(IntPtr hWnd, out uint lpdwProcessId);

или

static extern uint GetWindowThreadProcessId(IntPtr hWnd, IntPtr ProcessId);

в этом случае a ref или out к" что-то " управляются ссылки на что-то, поэтому они внутренне преобразовано в IntPtr при передаче в собственный API. Так что out uint, С точки зрения собственного API, эквивалентно IntPtr.

объяснение: важно то,что "длина" параметров является правильной. int и uint равны для вызываемого API. И 32bit IntPtr так же.

обратите внимание, что некоторые типы (например,bool и char) имеют специальную обработку упаковщиком.

вы никогда не должны конвертировать int до IntPtr. Держите его как IntPtr и жить счастливо. Если вам нужно сделать некоторые математические операции, не поддерживаемые IntPtr используйте long (это 64 бита, поэтому пока у нас не будет Windows 128, там не будет никаких проблем :-) ).

IntPtr p = ...
long l = (long)p;
p = (IntPtr)l;

Я думаю, что ошибка cannot implicitly convert from uint to int относится к = заявление. Поле this.ProcessID is int, а GetWindowThreadProcessId возвращает uint.

попробуй такое

this.ProcessID = unchecked((int)GetWindowThreadProcessId(windowHandle.ToInt32(),0))

Я получал "арифметическая операция привела к переполнению", когда я был:

IntPtr handler = OpenSCManager(null, null, SC_MANAGER_CREATE_SERVICE);
if (handler.ToInt32() == 0) //throws Exception

вместо этого:

IntPtr handler = OpenSCManager(null, null, SC_MANAGER_CREATE_SERVICE);
if (handler == IntPtr.Zero) //OK