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函数时要特别注意的事情。