64位窗口上的P / Invoke是否需要与32位不同的签名?
当我创建一个引用user32.dll
的签名时,如果目标是64位计算机,我应该用user64.dll
构建它吗?
[DllImport("user32.dll", CharSet = CharSet.Auto)] public static extern bool ChangeClipboardChain( IntPtr hWndRemove, IntPtr hWndNewNext);
目前这不是问题,因为我的目标只是32位,因为来自供应商(Progress OpenEdge)的库只提供32位库来访问他们的数据库。
我目前没有64位Windows计算机,看看是否是这种情况。
尽管命名约定,user32.dll(和其他32 … dll)实际上是64位机器上的64位。 这些是dll的历史名称,无论底层架构如何变化,都保持这种方式。 阅读此页面以获取更多详细信息。
在调用USER32.DLL函数时,您不需要更改链接到的DLL的签名/名称。
尽管存在命名约定,但在64位Windows机器上,位于[Windows] \ System32中的USER32.DLL文件实际上是64位DLL。 真正的 32位版本的USER32.DLL实际上位于名为[Windows] \ SysWow64的文件夹中。
有关详细信息,请参阅此问题 。
您可能需要特别注意的一件事是作为参数传递给各种Windows API函数的数据类型。 例如,USER32.DLL中的“SendMessage”函数具有至少一个参数的特定要求(根据P / Invoke上的页面 )。
它的签名是:
[DllImport("user32.dll", CharSet = CharSet.Auto)] static extern IntPtr SendMessage(IntPtr hWnd, UInt32 Msg, IntPtr wParam, IntPtr lParam);
以及下面的注释2和3明确说明:
2)永远不要使用“int”或“integer”作为lParam。 您的代码将在64位窗口上崩溃。 仅使用IntPtr,“ref”结构或“out”结构。
3)永远不要使用“bool”,“int”或“integer”作为返回值。 您的核心将在64位窗口上崩溃。 只使用IntPtr。 使用bool是不安全的 – pInvoke不能将IntPtr编组为布尔值。
这个“警告”似乎特定于这个特定的function(SendMessage),虽然这是我在调用任何 Windows API函数时要特别注意的事情。