当你有句柄时 int 与 IntPtr?
首先是一个背景问题:
一般来说,int
和 IntPtr
之间有什么区别?我的猜测是它是一个实际的对象,而不是像 int 或 byte 那样的值。假设这是真的:
所以它们不一样。但我看到句柄同时表示为两者。
- IntPtr:
Control.Handle
-
int(或uint):可以将PInvoke设置为返回
int
并且它工作得很好:[DllImport("coredll.dll", SetLastError = true)] 公共静态 extern int GetForegroundWindow(); 私有字符串 GetActiveWindow() { 常量 int nChars = 256; int 句柄 = 0; StringBuilder Buff = new StringBuilder(nChars); 句柄= CoreDLL.GetForegroundWindow(); if (CoreDLL.GetWindowText(handle, Buff, nChars) > 0) { 返回 Buff.ToString(); } 返回 ””; }
所以,int
与 IntPtr?跟手柄有关系吗?两者都可以用吗?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
int
长度为 32 位。IntPtr
与您的架构的指针一样长。因此,指针只能在 32 位系统上存储到int
中,而它总是可以存储在IntPtr
中。请注意,您的“int 作为返回值”示例并没有使用
int
来保存指针,而只是保存数值。但这并不意味着int
自动具有正确的大小:该 P/Invoke 签名的作者应该查看GetForegroundWindow
并查看它返回一个HWND
。然后,从 Platform SDK 中的
windef.h
(或 这个 MSDN 页面)我们可以看到HWND
是一个HANDLE
,它是一个PVOID
,它是……一个指针!因此,据我所知,该签名是错误的,因为 GetForegroundWindow 返回值的大小取决于体系结构。因此,它也应该是一个
IntPtr
。更新:
虽然可以从上面推断出来,但我认为有必要明确指出:
int
而不是IntPtr
位应用程序永远不会引起问题,即使它们在 64 位 Windows 上运行;由于此时大多数应用程序都是 32 位的,因此这可以让您经常避免此类错误。int
而不是IntPtr
不保证会导致问题,因为在实践中这些值很可能是遇到的将适合int
的 32 位。这进一步降低了错误表现为应用程序错误的可能性。因此,要真正显示错误,必须同时满足三个条件:
IntPtr
的地方使用int
。int
的值实际上大于 32 位。int
is 32 bits long.IntPtr
is as long as a pointer for your architecture. Therefore, a pointer can be stored into anint
only on 32 bit systems, while it can always be stored in anIntPtr
.Notice that your "int as a return value" example does not use an
int
to hold a pointer, but just to hold a numeric value. This does not mean that anint
is automatically the correct size though: the author of that P/Invoke signature should have gone to the documentation forGetForegroundWindow
and see that it returns aHWND
.Then, from
windef.h
in the Platform SDK (or this MSDN page) we can see that aHWND
is aHANDLE
which is aPVOID
which is... a pointer!Therefore, as far as I can tell, that signature is wrong, as the size of the return value of
GetForegroundWindow
depends on the architecture. Thus, it should also be anIntPtr
.Update:
While it can be inferred from the above, I think it's worthwhile to explicitly point out that:
int
instead ofIntPtr
in 32-bit applications will never cause a problem, even if they run on 64-bit Windows; since most applications are 32-bit at this point in time, this will let you get away such mistakes very often.int
instead ofIntPtr
in 64-bit applications is not guaranteed to cause problems, since it is quite possible that in practice the values being encountered will fit in the 32 bits of theint
. This further lessens the probability that a mistake will manifest as an application error.Therefore, for an error to actually manifest there are three conditions that have to be satisfied at the same time:
int
is used where anIntPtr
should be.int
is actually larger than 32 bits.