【问题标题】:Is it necessary to utilize the IntPtr constructor to set an IntPtr to equal another IntPtr?是否有必要利用 IntPtr 构造函数将 IntPtr 设置为等于另一个 IntPtr?
【发布时间】:2019-04-11 16:12:28
【问题描述】:

我目前正在将应用程序重构为 64 位,并且正在尝试了解 IntPtr 的特定用途。我试图理解的代码格式如下:

IntPtr a = Marshal.AllocHGlobal(SomeObjectSize); //SomeObjectSize is calculated based on some standard
IntPtr b = IntPtr(a.ToInt32());

现在乍一看,我想我可以将a.ToInt32() 更改为a.ToInt64(),这适用于需要将int 更改为IntPtr 的情况,但由于ab 都是IntPtr 类型,我不能只使用 IntPtr b = a;,因为 IntPtr 是值类型吗?我认为这将使我不必在这种情况下检查 64 位或 32 位版本,而且 MSDN 文档似乎并没有暗示 IntPtr 构造函数中有任何魔法。

基本上我的问题是我为什么要使用

IntPtr a = Marshal.AllocHGlobal(SomeObjectSize);
IntPtr b = IntPtr(a.ToInt32());

结束

IntPtr a = Marshal.AllocHGlobal(SomeObjectSize);
IntPtr b = a;

?

【问题讨论】:

  • 如果您有一个来自 Windows 95 的 16 位地址,您需要将其设为 32 位地址,而不是 64 位地址到 32。IntPtr 仅为 32 位以实现兼容性并采用 64位地址并将其设为 32 位会导致异常。
  • @jdweng 我正在处理的确切问题是用 64 位编译,我在 IntPtr(a.ToInt32()) 的行上遇到算术溢出异常
  • 算术溢出与 IntPtr 无关。从 IntPtr 返回的数字可以是任意大小(8、16、32、64)。错误发生在您对结果进行的数学运算中。如果您要添加两个 int16,则您的代码会将 [a.ToInt32()] int16 更改为 int32 因此,如果结果仅假设为 int16,则 int32 + int32 会出错。
  • 不要使用那个构造函数,你只需要一个简单的赋值。

标签: c# intptr


【解决方案1】:

你不仅可以使用

IntPtr b = a;

保存用于获取指针的信息,但您应该使用它来确保不同平台的兼容性。IntPtr 是特定于平台的类型(请参阅there),其大小取决于平台位数以自动适应指针大小。

但是,IntPtr 是多用途类型,它不仅用于保存指针信息,还用于各种 Windows API 句柄,以便在 Win API 互操作中使用(不过,这主要由运行时和 CTS 使用,很少由外部应用程序)。许多这些句柄(如窗口句柄、图标句柄、文件句柄、注册表句柄等)具有 32 位大小,这就是 IntPtr 应该用特定大小的整数初始化的地方,也是 IntPtr(int value) 构造函数出现的地方发挥作用。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-08-23
    • 2013-04-05
    • 2015-01-25
    • 2017-05-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多