winForms Interop - C#:WndProc() 和 IntPtr 类型 - 如何正确处理它?IntPtr
本文关键字:IntPtr 类型 正确处理 Interop WndProc winForms | 更新日期: 2023-09-27 17:56:16
我有WndProc(Message m)
覆盖。这显然被称为很多。假设我希望将某些消息标记为"已处理"。所以我应该将Result
设置为 1。但Result
财产是IntPtr
.执行m.Result = new IntPtr(1)
时会发生什么?每次调用都会为一个Int32
值分配内存?如果我创建一个静态IntPtr
变量并将其设置为 new IntPtr(1)
会发生什么?
最正确的方法是什么?
然后我想m.LParam
与已知值进行比较。它也IntPtr
,我可以通过多种方式做到这一点:
if (m.LParam == (IntPtr)0x0001) ...
if ((int)m.LParam == 0x0001) ...
if (m.LParam == myStaticIntPtr1) ...
这种比较的成本是多少?在高于 3 期间,低水平会发生什么? Message
类型不是一次性的。所以我认为我可以安全地省略将其传递给base.WndProc()
,对吗?当我只想丢弃消息时,不需要对它执行任何操作?
奖励问题:我不确定,但我想我已经在 pinvoke.net 上看到了 DllImport
MSDN 文档中存在的 IntPtr
更改为仅 int
s。 可能吗?行得通吗?会发生什么?隐式转换?
顺便说一句,IntPtr
是托管类型,对吧?因此,如果我不调用非托管代码或使用一次性类型 - 不需要释放任何东西?
IntPtr
是一种值类型,不会产生任何内存分配 - 它要么在堆栈上,要么是另一种类型的内存结构的一部分。在 C# 中,new
运算符同时用于值和引用类型,如果您来自C++背景,这可能会令人困惑。您甚至可以写new int()
,并且不会有任何分配。
此外,将其强制转换为Int32
( int
在 C# 中)可能会产生错误的结果 - 在 64 位进程中,它将是一个Int64
的大小(您可以检查IntPtr.Size
)。
简而言之,比较的成本可以忽略不计 - 这与比较两个整数相同。如果这样可以提高可读性,您可以将IntPtr
保留在静态字段中,但您不必担心内存。
以下内容是等效的:
-
new IntPtr(1)
-
(IntPtr)1
- 有一个显式强制转换运算符将其转换为上述构造函数
此类型存在的原因是在处理非托管 API 时抽象出指针的大小,因此您可以从 32 位和 64 位进程 P/Invoke 到 Win32 中。