Как конвертировать 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