当我创建引用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计算机,看看是否是这种情况。
答案 0 :(得分:12)
尽管有命名约定,user32.dll(和其他32 ... dll)在64位计算机上实际上是64位。这些是dll的历史名称,并且无论底层架构如何变化,都保持这种方式。阅读this页面以获取更多详细信息。
答案 1 :(得分:5)
您应该不在调用USER32.DLL函数时更改链接到的DLL的签名/名称。
尽管存在命名约定,但在64位Windows机器上,位于[Windows] \ System32中的USER32.DLL文件实际上是64位DLL。 真正的 32位版本的USER32.DLL实际上位于名为[Windows] \ SysWow64的文件夹中。
有关详细信息,请参阅this question。
您可能需要特别注意的一件事是您作为参数传递给各种Windows API函数的数据类型。例如,USER32.DLL中的“SendMessage”函数具有至少一个参数的特定要求(根据page on 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,一个“参考” 结构,或“外”结构。
3)永远不要使用“bool”,“int”或 “整数”作为返回值。您的 核心将在64位窗口上崩溃。 只使用IntPtr。这是不安全的使用 bool - pInvoke不能编组 IntPtr为布尔值。
这个“警告”似乎特定于此特定功能(SendMessage),尽管在调用任何 Windows API函数时我会特别注意这一点。