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

C# 64位windows上的P/Invoke是否需要与32位windows上不同的签名?,c#,64-bit,pinvoke,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 OpenEd

例如,当我创建一个引用
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。USER32.DLL的实际32位版本实际上位于名为[Windows]\SysWow64的文件夹中

有关更多信息,请参阅

您可能需要特别注意的一件事是作为参数传递给各种Windows API函数的数据类型。例如,USER32.DLL中的“SendMessage”函数对其至少一个参数有特定要求(根据)

签名是:

[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”或 “整数”作为返回值。你的 core将在64位windows上崩溃。 只使用IntPtr。使用起来不安全 布尔-平沃克无法封送 将IntPtr转换为布尔值


虽然在调用任何Windows API函数时,我都会特别注意这个“警告”,但这个“警告”似乎是特定于此特定函数(SendMessage)的。

天哪,页面描述文件系统视图在64/32位应用程序之间如何变化的方式让人相当害怕。非常感谢你的回答,皮特。谢谢你的回答,克雷格,太好了。我有一个问题,为什么
System.Windows.Forms.Message.Msg
的类型是
int
。之所以问这个问题,是因为这将在
Msg
中用于
SendMsg
,之前我在使用
int
@Brett的同一个签名中使用,这是个好问题,我不知道确切的答案,但是,这可能与SendMessage签名将Msg参数作为UInt32,并且.NET int始终是32位有关(与底层windows平台无关),而IntPtr结构旨在反映底层windows平台(即,在32位windows上是32位结构,但在64位windows上是64位结构).必须承认,这只是我的猜测。我很想知道确切的答案。是的,我想;有趣的是,它是
int
而不是
uint
,因为
UInt32
Int32
有不同的上限/下限,但是,任何发送0-I之外的内容的人无论如何,nt32.MaxValue都会出错。这只是一个观察:)@Brett@Craig区别在于uint不是CLR类型,而int是。这是有用的信息。但它确实影响了对该方法调用的类型转换。例如,过去是什么“SendMessage(parent.Handle,WM_SETREDRAW,false,0);”现在是“SendMessage(parent.Handle,WM_SETREDRAW,(IntPtr)0,(IntPtr)0);”等