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

Bre*_*yan 7 c# 64-bit pinvoke

当我创建一个引用的签名时,user32.dll例如,user64.dll如果目标是64位计算机,我应该构建它吗?

[DllImport("user32.dll", CharSet = CharSet.Auto)]
public static extern bool ChangeClipboardChain(
    IntPtr hWndRemove,
    IntPtr hWndNewNext);
Run Code Online (Sandbox Code Playgroud)

目前这不是问题,因为我的目标只是32位,因为来自供应商(Progress OpenEdge)的库只提供32位库来访问他们的数据库.

我目前没有64位Windows计算机,看看是否是这种情况.

Pet*_*lon 12

尽管命名约定,user32.dll(和其他32 ... dll)在64位机器上实际上是64位.这些是dll的历史名称,并且无论底层架构如何变化,都保持这种方式.阅读页面以获取更多详细信息.


Cra*_*gTP 5

你应该不会需要更改您链接调用到USER32.DLL功能时,该DLL的签名/名称.

尽管命名约定,在64位Windows机器上,位于[Windows]\System32中的USER32.DLL文件实际上是64位DLL.在实际 USER32.DLL的32位版本实际上位于一个名为[窗口]\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);
Run Code Online (Sandbox Code Playgroud)

以及下面的注释2和3明确说明:

2)永远不要使用"int"或"integer"作为lParam.您的代码将在64位窗口上崩溃.仅使用IntPtr,"ref"结构或"out"结构.

3)永远不要使用"bool","int"或"integer"作为返回值.您的核心将在64位窗口上崩溃.只使用IntPtr.使用bool是不安全的 - pInvoke不能将IntPtr编组为布尔值.

这个"警告"似乎是特定于这个特定的功能(SendMessage),虽然这是我在调用任何 Windows API函数时要特别注意的事情.