14

有时是类型的窗口句柄,有时是类型的窗口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

4

3 回答 3

14

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);

不要交换intIntPtr。它们仅在 32 位(大小相等)上几乎相等。在 64 位时,anIntPtr几乎等同于 a long(大小相等)

GetWindowThreadProcessId签名是

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

或者

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

在这种情况下,“某物”的 aref或 a 是out对某物的托管引用,因此它们IntPtr在传递给 Native API 时会在内部转换为。所以out uint,从 Native API 的角度来看,相当于IntPtr.

解释:重要的是参数的“长度”是正确的。int并且uint对于被调用的 API 是相等的。32位IntPtr也是一样的。

请注意,某些类型(如boolchar)具有编组器的特殊处理。

您不应该将 an 转换intIntPtr. 保持它,IntPtr并快乐地生活。如果您必须进行一些不支持的数学运算IntPtr,请使用long(它是 64 位,所以在我们拥有Windows 128之前,不会有任何问题 :-))。

IntPtr p = ...
long l = (long)p;
p = (IntPtr)l;
于 2013-08-11T15:00:38.510 回答
2

我认为该错误cannot implicitly convert from uint to int是指=陈述。该字段this.ProcessIDint,但GetWindowThreadProcessId返回uint

尝试这个

this.ProcessID = unchecked((int)GetWindowThreadProcessId(windowHandle.ToInt32(),0))
于 2013-08-11T15:17:14.113 回答
1

每当我出现以下情况时,我都会收到“算术运算导致溢出”:

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
于 2018-09-07T07:23:38.253 回答