64位窗口上的P / Invoke是否需要不同于32位的签名?

时间:2009-09-15 10:12:10

标签: c# 64-bit pinvoke

当我创建引用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计算机,看看是否是这种情况。

2 个答案:

答案 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函数时我会特别注意这一点。