我们可以用 DllImport 方法签名中的 "IntPtr" 替换所有 "int" 参数和 return 类型吗?

Can we replace all "int" parameter & return types with "IntPtr" in the DllImport method signature?

在我的程序中,我有一些 DllImport 因为我想调用一些本机 API。 int 类型用于方法参数和 returns 类型。在我 运行 我的应用程序在新的 Windows 2012 R2 服务器(64 位)上运行之前,它一直运行良好。当我将其中一个 ref 参数的类型从 int 更改为 IntPtr 时,问题得到解决。

我知道IntPtr是用来表示指针或者句柄的。 但是,MSDN 还说 IntPtr 是 "designed to be an integer",其大小是特定于平台的。因此,如果 IntPtr 能够处理平台特定大小的整数,是否可以将所有 int 参数和 return 类型替换为 IntPtr

我正在使用 C# .NET 4.0。

不,你不能盲目地这样做。 64 位代码仍然大量使用 32 位整数类型,它们的 "native integer" 仍然是 32 位值。如果您在本机代码声明(或等效的 typedef 别名)中看到 intlong,那么您仍然使用 int 在你的 pinvoke 声明中。

虽然对于 64 位编译器来说这听起来不是一件很明智的事情,但他们没有升级其原生整数类型是有充分理由的。现代处理器的速度非常快,但受限于它们寻址内存的速度。他们的执行引擎 运行 速度为千兆赫兹,但内存总线速度极慢。与距离相关的电气设计问题,信号传输的距离越远,它改变状态所需的速度就越慢,才能在电线的另一端正确识别。通过使用 caches(靠近执行引擎的内存副本)部分解决了一个问题。这些缓存的大小不会加倍。有效地使用缓存对速度来说非常重要,因此尽可能使用 32 位整数值很重要。

IntPtr 的本机类型示例是任何指针类型,size_t、XXX_PTR、WPARAM、LRESULT。后者是 typedef,它们会使识别底层类型变得困难。如有疑问,请编写一个使用 sizeof 的小 C 程序,以便您了解一个事实。

正式定义是64位本地编译器使用的data model。 Microsoft 编译器使用 LLP64。

is it OK to replace all int parameters & return types with IntPtr

不,不是。您需要单独查看每个用例。如果需要指针(例如接收输出),那么 IntPtr 更可能是正确的,因为它会根据您发现的平台指针宽度正确调整大小。

C# int is 32-bits regardless of whether the the underlying OS is 32 or 64 bits and will match corresponding fixed width parameter types in the Win32 API. LONG is one example with DWORD as its unsigned equivalent. There are others,许多其他...