64 位 Windows 上的 P/Invoke 是否需要与 32 位 Windows 上不同的签名?

发布于 2024-08-05 14:49:10 字数 383 浏览 4 评论 0原文

例如,当我创建引用 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电脑,想看看是否是这种情况。

When I create a signature that refers to user32.dll for example should I be building this with user64.dll if the target is a 64-bit computer?

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

Currently this isn't a problem as I'm targeting only 32-bit due to a library from a vendor (Progress OpenEdge) which only provide 32-bit libraries to access their database.

I don't currently have a 64-bit windows computer to see if this is the case.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

悲欢浪云 2024-08-12 14:49:10

尽管有命名约定,user32.dll(和其他 32...dll)实际上在 64 位计算机上是 64 位。这些是 dll 的历史名称,并且无论底层体系结构如何更改,都将保留这种名称。阅读页面以获取更多详细信息。

Despite the naming convention, user32.dll (and other 32... dlls) are actually 64 bit on 64 bit machines. These are the historical names for the dlls, and have been kept that way regardless of the changes to the underlying architecture. Have a read of this page to get more details.

萌能量女王 2024-08-12 14:49:10

在调用 USER32.DLL 函数时,您不需要需要更改链接到的 DLL 的签名/名称。

尽管有命名约定,但在 64 位 Windows 计算机上,位于 [Windows]\System32 中的 USER32.DLL 文件实际上是一个 64 位 DLL。 USER32.DLL 的真实 32 位版本实际上位于名为 [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”作为
l参数。你的代码在 64 位上会崩溃
视窗。仅使用 IntPtr,一个“ref”
结构,或“out”结构。

3) 切勿使用“bool”、“int”或
“整数”作为返回值。你的
核心将在 64 位 Windows 上崩溃。
仅使用 IntPtr。使用起来不安全
bool - pInvoke 无法封送
IntPtr 为布尔值。

这个“警告”似乎是特定于这个特定函数(SendMessage)的,尽管我在调用任何 Windows API 函数时会特别注意这一点。

You should not need to change the signature/name of the DLL that you link to when calling in to USER32.DLL functions.

Despite the naming convention, on a 64-bit Windows machine, the USER32.DLL file that sits in [Windows]\System32 is actually a 64-bit DLL. The real 32-bit version of USER32.DLL actually sits in a folder called [Windows]\SysWow64.

Please see this question for further info.

The one thing you'll probably need to be most careful of is the datatypes that you pass in as parameters to the various Windows API functions. For example, the "SendMessage" function within USER32.DLL has a specific requirement with at least one of it's parameters (according to the page on P/Invoke).

It's signature is:

[DllImport("user32.dll", CharSet = CharSet.Auto)]
static extern IntPtr SendMessage(IntPtr hWnd, UInt32 Msg, IntPtr wParam, IntPtr lParam);

and notes 2 & 3 below clearly state:

2) NEVER use "int" or "integer" as
lParam. Your code WILL crash on 64-bit
windows. ONLY use IntPtr, a "ref"
structure, or an "out" structure.

3) NEVER use "bool", "int", or
"integer" as the return value. Your
core WILL crash on 64-bit windows.
ONLY use IntPtr. It's not safe to use
bool - pInvoke cannot marshal an
IntPtr to a boolean.

This "caveat" appears to be specific to this particular function (SendMessage), although it's something I would pay particular attention to when calling into any Windows API functions.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文