C#:WndProc()和IntPtr类型 - 如何正确处理? IntPtr类型是否需要特别注意?

时间:2016-07-10 13:28:33

标签: c# winforms-interop

我有Result覆盖。这显然被称为很多。假设我想将一些消息标记为“已处理”。所以我应该将Result设置为1.但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) ... ,我可以通过以下几种方式做到:

Message

此类比较的成本是多少?在3级以上的低水平会发生什么? base.WndProc()类型不是一次性的。所以我想我可以安全地省略将其传递给DllImport,我是对的吗?当我只想丢弃信息时,没有什么需要做的吗?

奖金问题:我不确定,但我想我在pinvoke.net上看到了IntPtr,其中MSDN文档中的int已更改为IntPtr s 。可能?它有用吗?怎么了?隐式转换?

BTW,{{1}}是托管类型,对吗?所以如果我不调用非托管代码也不使用一次性类型 - 不需要处理任何东西?

1 个答案:

答案 0 :(得分:1)

IntPtr是一种值类型,不会导致任何内存分配 - 它可能位于堆栈上,也可能是其他类型内存结构的一部分。在C#中,new运算符用于值和引用类型,如果您来自C ++背景,这可能会令人困惑。你甚至可以写new int(),然后又不会有任何分配。

此外,将其转换为Int32(C#中的int)可能会产生错误的结果 - 在64位进程中,它将是Int64的大小(您可以检查) IntPtr.Size)。

简而言之,比较的成本可以忽略不计 - 它与比较两个整数相同。如果可以提高可读性,您可以将IntPtr保留在静态字段中,但是您不必担心内存。

以下是等效的:

  • new IntPtr(1)
  • (IntPtr)1 - 有一个显式的强制转换操作符,可将其转换为上述构造函数

此类型存在的原因是在处理非托管API时抽象出指针的大小,因此您可以从32位和64位进程P / Invoke到Win32。